Compare commits
No commits in common. "22afdb20a4df97a4c5abda6ee1988699b61097d0" and "ad868c0c257a7dfdd960fb681ddceb9d4a99d0b0" have entirely different histories.
22afdb20a4
...
ad868c0c25
18 changed files with 1439 additions and 2298 deletions
1482
game/client.c
1482
game/client.c
File diff suppressed because it is too large
Load diff
1174
game/client.c.bak
1174
game/client.c.bak
File diff suppressed because it is too large
Load diff
218
game/client.sui
218
game/client.sui
|
|
@ -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
|
||||||
23
src/ast.rs
23
src/ast.rs
|
|
@ -11,7 +11,6 @@ pub enum TypeAnnot {
|
||||||
Function(Vec<TypeAnnot>, Box<TypeAnnot>),
|
Function(Vec<TypeAnnot>, Box<TypeAnnot>),
|
||||||
Tuple(Vec<TypeAnnot>),
|
Tuple(Vec<TypeAnnot>),
|
||||||
Array(Box<TypeAnnot>),
|
Array(Box<TypeAnnot>),
|
||||||
FixedArray(Box<TypeAnnot>, i64),
|
|
||||||
Ptr(Box<TypeAnnot>),
|
Ptr(Box<TypeAnnot>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -67,7 +66,6 @@ pub enum ASTNodeKind {
|
||||||
Function(Function),
|
Function(Function),
|
||||||
Extern(Extern),
|
Extern(Extern),
|
||||||
Load(Load),
|
Load(Load),
|
||||||
Const(Const),
|
|
||||||
Struct(Struct),
|
Struct(Struct),
|
||||||
Enum(Enum),
|
Enum(Enum),
|
||||||
Impl(Impl),
|
Impl(Impl),
|
||||||
|
|
@ -81,13 +79,6 @@ pub struct Use {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Const {
|
|
||||||
pub name: String,
|
|
||||||
pub typ: Option<TypeAnnot>,
|
|
||||||
pub value: Expr,
|
|
||||||
}
|
|
||||||
|
|
||||||
// ? implies OPTIONAL here
|
// ? implies OPTIONAL here
|
||||||
// \( implies the presence of (. same for /)
|
// \( implies the presence of (. same for /)
|
||||||
|
|
||||||
|
|
@ -213,12 +204,10 @@ pub struct Expr {
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum ExprKind {
|
pub enum ExprKind {
|
||||||
Int(i64),
|
Int(i64),
|
||||||
TypedInt(i64, String),
|
|
||||||
Float(f64),
|
Float(f64),
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
String(String),
|
String(String),
|
||||||
Array(Vec<Expr>),
|
Array(Vec<Expr>),
|
||||||
FixedArray(Box<Expr>, i64),
|
|
||||||
Tuple(Vec<Expr>),
|
Tuple(Vec<Expr>),
|
||||||
|
|
||||||
StructLit(String, Vec<(String, Expr)>), // Name { a: expr, b: expr }
|
StructLit(String, Vec<(String, Expr)>), // Name { a: expr, b: expr }
|
||||||
|
|
@ -273,8 +262,6 @@ pub enum BinOp {
|
||||||
Or,
|
Or,
|
||||||
BitwiseAnd,
|
BitwiseAnd,
|
||||||
BitwiseOr,
|
BitwiseOr,
|
||||||
LShift,
|
|
||||||
RShift,
|
|
||||||
Eq,
|
Eq,
|
||||||
Neq,
|
Neq,
|
||||||
Lt,
|
Lt,
|
||||||
|
|
@ -324,7 +311,6 @@ pub enum TypedASTNodeKind {
|
||||||
Function(TypedFunction),
|
Function(TypedFunction),
|
||||||
Extern(TypedExtern),
|
Extern(TypedExtern),
|
||||||
Load(TypedLoad),
|
Load(TypedLoad),
|
||||||
Const(TypedConst),
|
|
||||||
Struct(TypedStruct),
|
Struct(TypedStruct),
|
||||||
Enum(TypedEnum),
|
Enum(TypedEnum),
|
||||||
Impl(TypedImpl),
|
Impl(TypedImpl),
|
||||||
|
|
@ -358,13 +344,6 @@ pub struct TypedLoad {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct TypedConst {
|
|
||||||
pub name: String,
|
|
||||||
pub typ: Option<TypeAnnot>,
|
|
||||||
pub value: TypedExpr,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TypedStruct {
|
pub struct TypedStruct {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
@ -419,12 +398,10 @@ pub struct TypedExpr {
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum TypedExprKind {
|
pub enum TypedExprKind {
|
||||||
Int(i64),
|
Int(i64),
|
||||||
TypedInt(i64, String),
|
|
||||||
Float(f64),
|
Float(f64),
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
String(String),
|
String(String),
|
||||||
Array(Vec<TypedExpr>),
|
Array(Vec<TypedExpr>),
|
||||||
FixedArray(Box<TypedExpr>, usize),
|
|
||||||
Tuple(Vec<TypedExpr>),
|
Tuple(Vec<TypedExpr>),
|
||||||
StructLit(String, Vec<(String, TypedExpr)>),
|
StructLit(String, Vec<(String, TypedExpr)>),
|
||||||
EnumLit(String, String, Vec<TypedExpr>),
|
EnumLit(String, String, Vec<TypedExpr>),
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
pub enum CType {
|
pub enum CType {
|
||||||
Void,
|
Void,
|
||||||
Int,
|
Int,
|
||||||
U8,
|
|
||||||
Float,
|
Float,
|
||||||
Bool,
|
Bool,
|
||||||
Char,
|
Char,
|
||||||
|
|
@ -10,7 +9,6 @@ pub enum CType {
|
||||||
Struct(String),
|
Struct(String),
|
||||||
UnnamedStruct(Vec<CVarDecl>),
|
UnnamedStruct(Vec<CVarDecl>),
|
||||||
Array(Box<CType>), // heap-allocated array wrapper with data pointer, len, capacity
|
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
|
Func(Vec<CType>, Box<CType>), // args and return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -34,7 +32,6 @@ impl CType {
|
||||||
match self {
|
match self {
|
||||||
CType::Void => "void".to_string(),
|
CType::Void => "void".to_string(),
|
||||||
CType::Int => "int".to_string(),
|
CType::Int => "int".to_string(),
|
||||||
CType::U8 => "uint8_t".to_string(),
|
|
||||||
CType::Float => "float".to_string(),
|
CType::Float => "float".to_string(),
|
||||||
CType::Bool => "bool".to_string(),
|
CType::Bool => "bool".to_string(),
|
||||||
CType::Char => "char".to_string(),
|
CType::Char => "char".to_string(),
|
||||||
|
|
@ -51,7 +48,6 @@ impl CType {
|
||||||
"struct sui_array_{}",
|
"struct sui_array_{}",
|
||||||
inner.to_string().replace(" ", "_").replace("*", "ptr")
|
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) => {
|
CType::Func(args, ret) => {
|
||||||
let arg_strs: Vec<String> = args.iter().map(|t| t.to_string()).collect();
|
let arg_strs: Vec<String> = args.iter().map(|t| t.to_string()).collect();
|
||||||
format!("{} (*)({})", ret.to_string(), arg_strs.join(", "))
|
format!("{} (*)({})", ret.to_string(), arg_strs.join(", "))
|
||||||
|
|
@ -65,7 +61,6 @@ pub struct CVarDecl {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub ty: CType,
|
pub ty: CType,
|
||||||
pub initializer: Option<CExpr>,
|
pub initializer: Option<CExpr>,
|
||||||
pub is_const: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
|
@ -121,8 +116,6 @@ pub enum CBinaryOp {
|
||||||
Or,
|
Or,
|
||||||
BitwiseAnd,
|
BitwiseAnd,
|
||||||
BitwiseOr,
|
BitwiseOr,
|
||||||
LShift,
|
|
||||||
RShift,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CBinaryOp {
|
impl CBinaryOp {
|
||||||
|
|
@ -143,8 +136,6 @@ impl CBinaryOp {
|
||||||
CBinaryOp::Or => "||",
|
CBinaryOp::Or => "||",
|
||||||
CBinaryOp::BitwiseAnd => "&",
|
CBinaryOp::BitwiseAnd => "&",
|
||||||
CBinaryOp::BitwiseOr => "|",
|
CBinaryOp::BitwiseOr => "|",
|
||||||
CBinaryOp::LShift => "<<",
|
|
||||||
CBinaryOp::RShift => ">>",
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ impl DeclarationTranspiler {
|
||||||
name: field.name.clone(),
|
name: field.name.clone(),
|
||||||
ty: field_type,
|
ty: field_type,
|
||||||
initializer: None,
|
initializer: None,
|
||||||
is_const: false,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,7 +53,6 @@ impl DeclarationTranspiler {
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
ty: param_type,
|
ty: param_type,
|
||||||
initializer: None,
|
initializer: None,
|
||||||
is_const: false,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,7 +81,6 @@ impl DeclarationTranspiler {
|
||||||
name: field_name,
|
name: field_name,
|
||||||
ty: c_type,
|
ty: c_type,
|
||||||
initializer: None,
|
initializer: None,
|
||||||
is_const: false,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,7 +100,6 @@ impl DeclarationTranspiler {
|
||||||
name: field_name,
|
name: field_name,
|
||||||
ty: CType::Struct(struct_name),
|
ty: CType::Struct(struct_name),
|
||||||
initializer: None,
|
initializer: None,
|
||||||
is_const: false,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -119,13 +115,11 @@ impl DeclarationTranspiler {
|
||||||
name: "discriminant".to_string(),
|
name: "discriminant".to_string(),
|
||||||
ty: CType::Int,
|
ty: CType::Int,
|
||||||
initializer: None,
|
initializer: None,
|
||||||
is_const: false,
|
|
||||||
},
|
},
|
||||||
CVarDecl {
|
CVarDecl {
|
||||||
name: "data".to_string(),
|
name: "data".to_string(),
|
||||||
ty: CType::Struct(union_name_clone),
|
ty: CType::Struct(union_name_clone),
|
||||||
initializer: None,
|
initializer: None,
|
||||||
is_const: false,
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
@ -154,10 +148,6 @@ impl DeclarationTranspiler {
|
||||||
// Arrays are pointers to the element type
|
// Arrays are pointers to the element type
|
||||||
Ok(CType::Ptr(Box::new(inner_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)) => {
|
Some(TypeAnnot::Tuple(fields)) => {
|
||||||
let mut c_fields = Vec::new();
|
let mut c_fields = Vec::new();
|
||||||
for (i, field_annot) in fields.iter().enumerate() {
|
for (i, field_annot) in fields.iter().enumerate() {
|
||||||
|
|
@ -166,7 +156,6 @@ impl DeclarationTranspiler {
|
||||||
name: format!("field{}", i),
|
name: format!("field{}", i),
|
||||||
ty: field_type,
|
ty: field_type,
|
||||||
initializer: None,
|
initializer: None,
|
||||||
is_const: false,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Ok(CType::UnnamedStruct(c_fields))
|
Ok(CType::UnnamedStruct(c_fields))
|
||||||
|
|
@ -187,7 +176,6 @@ impl DeclarationTranspiler {
|
||||||
pub fn convert_to_c_type(name: &String) -> Result<CType, String> {
|
pub fn convert_to_c_type(name: &String) -> Result<CType, String> {
|
||||||
match String::as_str(name) {
|
match String::as_str(name) {
|
||||||
"int" => Ok(CType::Int),
|
"int" => Ok(CType::Int),
|
||||||
"u8" => Ok(CType::U8),
|
|
||||||
"float" => Ok(CType::Float),
|
"float" => Ok(CType::Float),
|
||||||
"bool" => Ok(CType::Bool),
|
"bool" => Ok(CType::Bool),
|
||||||
"string" => Ok(CType::Ptr(Box::new(CType::Char))),
|
"string" => Ok(CType::Ptr(Box::new(CType::Char))),
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@ impl StatementsTranspiler {
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
ty,
|
ty,
|
||||||
initializer,
|
initializer,
|
||||||
is_const: false,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
(name, decl)
|
(name, decl)
|
||||||
|
|
@ -49,13 +48,6 @@ impl StatementsTranspiler {
|
||||||
pub fn transpile_expr(&self, expr: &TypedExpr) -> Result<CExpr, String> {
|
pub fn transpile_expr(&self, expr: &TypedExpr) -> Result<CExpr, String> {
|
||||||
match &expr.kind {
|
match &expr.kind {
|
||||||
TypedExprKind::Int(i) => Ok(CExpr::IntLit(*i)),
|
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::Float(f) => Ok(CExpr::FloatLit(*f)),
|
||||||
TypedExprKind::Bool(b) => Ok(CExpr::BoolLit(*b)),
|
TypedExprKind::Bool(b) => Ok(CExpr::BoolLit(*b)),
|
||||||
TypedExprKind::String(s) => Ok(CExpr::StringLit(s.clone())),
|
TypedExprKind::String(s) => Ok(CExpr::StringLit(s.clone())),
|
||||||
|
|
@ -125,11 +117,6 @@ impl StatementsTranspiler {
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
Ok(CExpr::ArrayLit(c_exprs))
|
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) => {
|
TypedExprKind::Cast(expr, type_annot) => {
|
||||||
let c_expr = self.transpile_expr(expr)?;
|
let c_expr = self.transpile_expr(expr)?;
|
||||||
// Simplified: assuming we can map type annotations to C types
|
// Simplified: assuming we can map type annotations to C types
|
||||||
|
|
@ -183,7 +170,6 @@ impl StatementsTranspiler {
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
ty: c_type,
|
ty: c_type,
|
||||||
initializer,
|
initializer,
|
||||||
is_const: false,
|
|
||||||
};
|
};
|
||||||
Ok(CStmt::VarDecl(var_decl))
|
Ok(CStmt::VarDecl(var_decl))
|
||||||
}
|
}
|
||||||
|
|
@ -235,7 +221,6 @@ impl StatementsTranspiler {
|
||||||
name: var_name.clone(),
|
name: var_name.clone(),
|
||||||
ty: CType::Int,
|
ty: CType::Int,
|
||||||
initializer: Some(start_expr),
|
initializer: Some(start_expr),
|
||||||
is_const: false,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let cond = CExpr::BinOp(
|
let cond = CExpr::BinOp(
|
||||||
|
|
@ -287,7 +272,6 @@ impl StatementsTranspiler {
|
||||||
)),
|
)),
|
||||||
Box::new(CExpr::Var(idx_name.clone())),
|
Box::new(CExpr::Var(idx_name.clone())),
|
||||||
)),
|
)),
|
||||||
is_const: false,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut body_stmts = vec![bind];
|
let mut body_stmts = vec![bind];
|
||||||
|
|
@ -337,7 +321,6 @@ impl StatementsTranspiler {
|
||||||
Box::new(CExpr::Var(arr_name.clone())),
|
Box::new(CExpr::Var(arr_name.clone())),
|
||||||
Box::new(CExpr::Var(idx_name.clone())),
|
Box::new(CExpr::Var(idx_name.clone())),
|
||||||
)),
|
)),
|
||||||
is_const: false,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut body_stmts = vec![bind];
|
let mut body_stmts = vec![bind];
|
||||||
|
|
@ -473,8 +456,6 @@ impl StatementsTranspiler {
|
||||||
BinOp::Or => Ok(CBinaryOp::Or),
|
BinOp::Or => Ok(CBinaryOp::Or),
|
||||||
BinOp::BitwiseAnd => Ok(CBinaryOp::BitwiseAnd),
|
BinOp::BitwiseAnd => Ok(CBinaryOp::BitwiseAnd),
|
||||||
BinOp::BitwiseOr => Ok(CBinaryOp::BitwiseOr),
|
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 {
|
match ty {
|
||||||
Type::Int => Ok(CType::Int),
|
Type::Int => Ok(CType::Int),
|
||||||
Type::U8 => Ok(CType::U8),
|
|
||||||
Type::Float => Ok(CType::Float),
|
Type::Float => Ok(CType::Float),
|
||||||
Type::Bool => Ok(CType::Bool),
|
Type::Bool => Ok(CType::Bool),
|
||||||
Type::String => Ok(CType::Ptr(Box::new(CType::Char))),
|
Type::String => Ok(CType::Ptr(Box::new(CType::Char))),
|
||||||
|
|
@ -502,10 +482,6 @@ impl StatementsTranspiler {
|
||||||
// Arrays are pointers to the element type
|
// Arrays are pointers to the element type
|
||||||
Ok(CType::Ptr(Box::new(inner_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::Struct(name, _) => Ok(CType::Ptr(Box::new(CType::Struct(name.clone())))),
|
||||||
Type::Enum(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) => {
|
Type::Tuple(types) => {
|
||||||
|
|
@ -516,7 +492,6 @@ impl StatementsTranspiler {
|
||||||
name: format!("field{}", i),
|
name: format!("field{}", i),
|
||||||
ty: c_type,
|
ty: c_type,
|
||||||
initializer: None,
|
initializer: None,
|
||||||
is_const: false,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Ok(CType::UnnamedStruct(fields))
|
Ok(CType::UnnamedStruct(fields))
|
||||||
|
|
@ -561,10 +536,6 @@ impl StatementsTranspiler {
|
||||||
// Arrays are pointers to the element type
|
// Arrays are pointers to the element type
|
||||||
Ok(CType::Ptr(Box::new(inner_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) => {
|
TypeAnnot::Tuple(fields) => {
|
||||||
let mut c_fields = Vec::new();
|
let mut c_fields = Vec::new();
|
||||||
for (i, field_annot) in fields.iter().enumerate() {
|
for (i, field_annot) in fields.iter().enumerate() {
|
||||||
|
|
@ -573,7 +544,6 @@ impl StatementsTranspiler {
|
||||||
name: format!("field{}", i),
|
name: format!("field{}", i),
|
||||||
ty: field_type,
|
ty: field_type,
|
||||||
initializer: None,
|
initializer: None,
|
||||||
is_const: false,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Ok(CType::UnnamedStruct(c_fields))
|
Ok(CType::UnnamedStruct(c_fields))
|
||||||
|
|
|
||||||
|
|
@ -90,39 +90,6 @@ impl Transpiler {
|
||||||
self.lower_declarations_to_c_ir(node)?;
|
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)?;
|
self.lower_function_bodies_to_c_ir(nodes)?;
|
||||||
|
|
||||||
// Rename main to suic_main and track that we have a main
|
// Rename main to suic_main and track that we have a main
|
||||||
|
|
@ -271,16 +238,6 @@ impl Transpiler {
|
||||||
self.functions.push(func_decl);
|
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) => {
|
TypedASTNodeKind::Extern(e) => {
|
||||||
// For externs, we might need to add function prototypes
|
// For externs, we might need to add function prototypes
|
||||||
// But for now, skip as they're handled differently
|
// But for now, skip as they're handled differently
|
||||||
|
|
@ -447,26 +404,9 @@ impl Transpiler {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_var_decl(&self, var: &CVarDecl) -> String {
|
fn generate_var_decl(&self, var: &CVarDecl) -> String {
|
||||||
let mut output = match &var.ty {
|
let mut output = format!("{} {}", var.ty.to_string(), var.name);
|
||||||
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);
|
|
||||||
}
|
|
||||||
if let Some(init) = &var.initializer {
|
if let Some(init) = &var.initializer {
|
||||||
match (&var.ty, init) {
|
output.push_str(&format!(" = {}", self.generate_expr(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
|
output
|
||||||
}
|
}
|
||||||
|
|
@ -698,14 +638,13 @@ impl Transpiler {
|
||||||
"rl_pop_matrix" => "suic_rl_pop_matrix",
|
"rl_pop_matrix" => "suic_rl_pop_matrix",
|
||||||
"rl_translate_f" => "suic_rl_translate_f",
|
"rl_translate_f" => "suic_rl_translate_f",
|
||||||
"rl_rotate_f" => "suic_rl_rotate_f",
|
"rl_rotate_f" => "suic_rl_rotate_f",
|
||||||
// UI Framework Utils
|
// UI Framework Utils
|
||||||
"draw_text" => "DrawText",
|
"draw_text" => "suic_draw_text",
|
||||||
"draw_rectangle" => "DrawRectangle",
|
"draw_rectangle" => "suic_draw_rectangle",
|
||||||
"draw_rectangle_lines" => "DrawRectangleLines",
|
"draw_rectangle_lines" => "suic_draw_rectangle_lines",
|
||||||
"measure_text" => "MeasureText",
|
"measure_text" => "suic_measure_text",
|
||||||
"draw_circle" => "DrawCircle",
|
"draw_circle" => "suic_draw_circle",
|
||||||
"draw_line" => "DrawLine",
|
"draw_line" => "suic_draw_line",
|
||||||
"draw_fps" => "DrawFPS",
|
|
||||||
// Player controller functions
|
// Player controller functions
|
||||||
"player_controller_create" => "suic_player_controller_create",
|
"player_controller_create" => "suic_player_controller_create",
|
||||||
"player_controller_destroy" => "suic_player_controller_destroy",
|
"player_controller_destroy" => "suic_player_controller_destroy",
|
||||||
|
|
@ -796,7 +735,18 @@ impl Transpiler {
|
||||||
"Vec3" => "suic_vec3".to_string(),
|
"Vec3" => "suic_vec3".to_string(),
|
||||||
_ => format!("struct {}", struct_name),
|
_ => 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) => {
|
CExpr::EnumLit(enum_name, variant_name, args) => {
|
||||||
// Find the variant index - for simplicity, assume variants are in order
|
// Find the variant index - for simplicity, assume variants are in order
|
||||||
|
|
|
||||||
|
|
@ -370,22 +370,14 @@ impl ImportResolver {
|
||||||
ASTNodeKind::Load(_) => {
|
ASTNodeKind::Load(_) => {
|
||||||
result.push(node);
|
result.push(node);
|
||||||
}
|
}
|
||||||
ASTNodeKind::Trait(t) => {
|
ASTNodeKind::Trait(t) => {
|
||||||
self.symbol_registry.register(
|
self.symbol_registry.register(
|
||||||
t.name.clone(),
|
t.name.clone(),
|
||||||
filename.to_string(),
|
filename.to_string(),
|
||||||
node.span.clone(),
|
node.span.clone(),
|
||||||
)?;
|
)?;
|
||||||
result.push(node);
|
result.push(node);
|
||||||
}
|
}
|
||||||
ASTNodeKind::Const(c) => {
|
|
||||||
self.symbol_registry.register(
|
|
||||||
c.name.clone(),
|
|
||||||
filename.to_string(),
|
|
||||||
node.span.clone(),
|
|
||||||
)?;
|
|
||||||
result.push(node);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -126,9 +126,6 @@ impl LambdaLowerer {
|
||||||
self.collect_free_vars_expr(expr, lambda_params, free_vars, local_scope);
|
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) => {
|
ExprKind::Tuple(exprs) => {
|
||||||
for expr in exprs {
|
for expr in exprs {
|
||||||
self.collect_free_vars_expr(expr, lambda_params, free_vars, local_scope);
|
self.collect_free_vars_expr(expr, lambda_params, free_vars, local_scope);
|
||||||
|
|
@ -153,7 +150,6 @@ impl LambdaLowerer {
|
||||||
}
|
}
|
||||||
// Terminal expressions don't contain variables
|
// Terminal expressions don't contain variables
|
||||||
ExprKind::Int(_)
|
ExprKind::Int(_)
|
||||||
| ExprKind::TypedInt(_, _)
|
|
||||||
| ExprKind::Float(_)
|
| ExprKind::Float(_)
|
||||||
| ExprKind::Bool(_)
|
| ExprKind::Bool(_)
|
||||||
| ExprKind::String(_)
|
| ExprKind::String(_)
|
||||||
|
|
@ -344,10 +340,6 @@ impl LambdaLowerer {
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
ExprKind::Array(lowered_exprs)
|
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) => {
|
ExprKind::Tuple(exprs) => {
|
||||||
let lowered_exprs = exprs
|
let lowered_exprs = exprs
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -377,7 +369,6 @@ impl LambdaLowerer {
|
||||||
}
|
}
|
||||||
// Terminal expressions that don't contain other expressions
|
// Terminal expressions that don't contain other expressions
|
||||||
ExprKind::Int(_)
|
ExprKind::Int(_)
|
||||||
| ExprKind::TypedInt(_, _)
|
|
||||||
| ExprKind::Float(_)
|
| ExprKind::Float(_)
|
||||||
| ExprKind::Bool(_)
|
| ExprKind::Bool(_)
|
||||||
| ExprKind::String(_)
|
| ExprKind::String(_)
|
||||||
|
|
|
||||||
|
|
@ -20,14 +20,6 @@ pub enum Token {
|
||||||
}, priority = 4)]
|
}, priority = 4)]
|
||||||
Int(i64),
|
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| {
|
#[regex(r"(([0-9][0-9_]*\.[0-9_]+|[0-9]*\.[0-9_]+)([eE][+-]?[0-9_]+)?)", |lex| {
|
||||||
let s = lex.slice().replace("_", "");
|
let s = lex.slice().replace("_", "");
|
||||||
s.parse::<f64>().unwrap()
|
s.parse::<f64>().unwrap()
|
||||||
|
|
@ -69,9 +61,6 @@ pub enum Token {
|
||||||
#[token("string")]
|
#[token("string")]
|
||||||
KeywordString,
|
KeywordString,
|
||||||
|
|
||||||
#[token("u8")]
|
|
||||||
KeywordU8,
|
|
||||||
|
|
||||||
#[token("let")]
|
#[token("let")]
|
||||||
KeywordLet,
|
KeywordLet,
|
||||||
|
|
||||||
|
|
@ -146,9 +135,6 @@ pub enum Token {
|
||||||
#[token("trait")]
|
#[token("trait")]
|
||||||
KeywordTrait,
|
KeywordTrait,
|
||||||
|
|
||||||
#[token("const")]
|
|
||||||
KeywordConst,
|
|
||||||
|
|
||||||
// #[token("type")]
|
// #[token("type")]
|
||||||
// KeywordType,
|
// KeywordType,
|
||||||
//
|
//
|
||||||
|
|
@ -185,12 +171,6 @@ pub enum Token {
|
||||||
#[token("**", priority = 3)]
|
#[token("**", priority = 3)]
|
||||||
Power,
|
Power,
|
||||||
|
|
||||||
#[token("<<")]
|
|
||||||
LShift,
|
|
||||||
|
|
||||||
#[token(">>")]
|
|
||||||
RShift,
|
|
||||||
|
|
||||||
#[token("$")]
|
#[token("$")]
|
||||||
Dollar,
|
Dollar,
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -244,9 +244,6 @@ fn run_file(filename: &str, debug: bool) -> Result<(), String> {
|
||||||
suicmez::ast::TypedASTNodeKind::Function(f) => {
|
suicmez::ast::TypedASTNodeKind::Function(f) => {
|
||||||
format!("Function({})", f.name)
|
format!("Function({})", f.name)
|
||||||
}
|
}
|
||||||
suicmez::ast::TypedASTNodeKind::Const(c) => {
|
|
||||||
format!("Const({})", c.name)
|
|
||||||
}
|
|
||||||
suicmez::ast::TypedASTNodeKind::Struct(s) => {
|
suicmez::ast::TypedASTNodeKind::Struct(s) => {
|
||||||
format!("Struct({}) with {} params", s.name, s.parameters.len())
|
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) => {
|
suicmez::ast::TypedASTNodeKind::Function(f) => {
|
||||||
format!("Function({})", f.name)
|
format!("Function({})", f.name)
|
||||||
}
|
}
|
||||||
suicmez::ast::TypedASTNodeKind::Const(c) => {
|
|
||||||
format!("Const({})", c.name)
|
|
||||||
}
|
|
||||||
suicmez::ast::TypedASTNodeKind::Struct(s) => {
|
suicmez::ast::TypedASTNodeKind::Struct(s) => {
|
||||||
format!("Struct({}) with {} params", s.name, s.parameters.len())
|
format!("Struct({}) with {} params", s.name, s.parameters.len())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -104,9 +104,6 @@ impl Monomorphizer {
|
||||||
|
|
||||||
for (_idx, node) in nodes.iter().enumerate() {
|
for (_idx, node) in nodes.iter().enumerate() {
|
||||||
match &node.kind {
|
match &node.kind {
|
||||||
TypedASTNodeKind::Const(c) => {
|
|
||||||
result_nodes.push(node.clone());
|
|
||||||
}
|
|
||||||
TypedASTNodeKind::Function(f) => {
|
TypedASTNodeKind::Function(f) => {
|
||||||
// Skip generic functions - they'll be added as specialized versions when needed
|
// Skip generic functions - they'll be added as specialized versions when needed
|
||||||
if !f.parameters.is_empty() {
|
if !f.parameters.is_empty() {
|
||||||
|
|
@ -325,7 +322,6 @@ impl Monomorphizer {
|
||||||
let mut needs = Vec::new();
|
let mut needs = Vec::new();
|
||||||
let new_kind = match &expr.kind {
|
let new_kind = match &expr.kind {
|
||||||
TypedExprKind::Int(_)
|
TypedExprKind::Int(_)
|
||||||
| TypedExprKind::TypedInt(_, _)
|
|
||||||
| TypedExprKind::Float(_)
|
| TypedExprKind::Float(_)
|
||||||
| TypedExprKind::Bool(_)
|
| TypedExprKind::Bool(_)
|
||||||
| TypedExprKind::String(_)
|
| TypedExprKind::String(_)
|
||||||
|
|
@ -346,11 +342,6 @@ impl Monomorphizer {
|
||||||
}
|
}
|
||||||
TypedExprKind::Array(new_elems)
|
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) => {
|
TypedExprKind::Tuple(elems) => {
|
||||||
let mut new_elems = Vec::new();
|
let mut new_elems = Vec::new();
|
||||||
|
|
@ -776,10 +767,6 @@ impl Monomorphizer {
|
||||||
let new_inner = self.substitute_in_type_annot(inner, subst_map)?;
|
let new_inner = self.substitute_in_type_annot(inner, subst_map)?;
|
||||||
Ok(TypeAnnot::Array(Box::new(new_inner)))
|
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) => {
|
TypeAnnot::Ptr(inner) => {
|
||||||
let new_inner = self.substitute_in_type_annot(inner, subst_map)?;
|
let new_inner = self.substitute_in_type_annot(inner, subst_map)?;
|
||||||
Ok(TypeAnnot::Ptr(Box::new(new_inner)))
|
Ok(TypeAnnot::Ptr(Box::new(new_inner)))
|
||||||
|
|
@ -790,13 +777,11 @@ impl Monomorphizer {
|
||||||
fn type_to_type_annot(&self, ty: &Type) -> TypeAnnot {
|
fn type_to_type_annot(&self, ty: &Type) -> TypeAnnot {
|
||||||
match ty {
|
match ty {
|
||||||
Type::Int => TypeAnnot::Var("int".to_string()),
|
Type::Int => TypeAnnot::Var("int".to_string()),
|
||||||
Type::U8 => TypeAnnot::Var("u8".to_string()),
|
|
||||||
Type::Float => TypeAnnot::Var("float".to_string()),
|
Type::Float => TypeAnnot::Var("float".to_string()),
|
||||||
Type::Bool => TypeAnnot::Var("bool".to_string()),
|
Type::Bool => TypeAnnot::Var("bool".to_string()),
|
||||||
Type::String => TypeAnnot::Var("string".to_string()),
|
Type::String => TypeAnnot::Var("string".to_string()),
|
||||||
Type::Unit => TypeAnnot::Tuple(Vec::new()),
|
Type::Unit => TypeAnnot::Tuple(Vec::new()),
|
||||||
Type::Array(inner) => TypeAnnot::Array(Box::new(self.type_to_type_annot(inner))),
|
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::Ptr(inner) => TypeAnnot::Ptr(Box::new(self.type_to_type_annot(inner))),
|
||||||
Type::Tuple(types) => {
|
Type::Tuple(types) => {
|
||||||
let annots = types.iter().map(|t| self.type_to_type_annot(t)).collect();
|
let annots = types.iter().map(|t| self.type_to_type_annot(t)).collect();
|
||||||
|
|
@ -916,9 +901,6 @@ impl Monomorphizer {
|
||||||
TypeAnnot::Array(inner) => {
|
TypeAnnot::Array(inner) => {
|
||||||
self.collect_needs_from_type(inner, needs);
|
self.collect_needs_from_type(inner, needs);
|
||||||
}
|
}
|
||||||
TypeAnnot::FixedArray(inner, _) => {
|
|
||||||
self.collect_needs_from_type(inner, needs);
|
|
||||||
}
|
|
||||||
TypeAnnot::Ptr(inner) => {
|
TypeAnnot::Ptr(inner) => {
|
||||||
self.collect_needs_from_type(inner, needs);
|
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();
|
let tys = types.iter().map(|t| self.type_annot_to_type(t)).collect();
|
||||||
Type::Tuple(tys)
|
Type::Tuple(tys)
|
||||||
}
|
}
|
||||||
TypeAnnot::Array(inner) => Type::Array(Box::new(self.type_annot_to_type(inner))),
|
TypeAnnot::Array(inner) => {
|
||||||
TypeAnnot::FixedArray(inner, size) => Type::FixedArray(Box::new(self.type_annot_to_type(inner)), *size as usize),
|
let inner_type = self.type_annot_to_type(inner);
|
||||||
|
Type::Array(Box::new(inner_type))
|
||||||
|
}
|
||||||
TypeAnnot::Ptr(inner) => {
|
TypeAnnot::Ptr(inner) => {
|
||||||
let inner_type = self.type_annot_to_type(inner);
|
let inner_type = self.type_annot_to_type(inner);
|
||||||
Type::Ptr(Box::new(inner_type))
|
Type::Ptr(Box::new(inner_type))
|
||||||
|
|
@ -991,9 +975,6 @@ fn check_node_for_typevars(node: &TypedASTNode) -> Result<(), MonomorphizationEr
|
||||||
TypedASTNodeKind::Function(f) => {
|
TypedASTNodeKind::Function(f) => {
|
||||||
check_function_for_typevars(f)?;
|
check_function_for_typevars(f)?;
|
||||||
}
|
}
|
||||||
TypedASTNodeKind::Const(c) => {
|
|
||||||
// Consts should not have typevars
|
|
||||||
}
|
|
||||||
TypedASTNodeKind::Struct(s) => {
|
TypedASTNodeKind::Struct(s) => {
|
||||||
check_struct_for_typevars(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::Tuple(types) => types.iter().any(has_typevars_in_type_annot),
|
||||||
TypeAnnot::Array(inner) => has_typevars_in_type_annot(inner),
|
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),
|
TypeAnnot::Ptr(inner) => has_typevars_in_type_annot(inner),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
149
src/parser.rs
149
src/parser.rs
|
|
@ -149,16 +149,6 @@ impl Parser {
|
||||||
attributes,
|
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) => {
|
Some(Token::KeywordStruct) => {
|
||||||
self.next();
|
self.next();
|
||||||
let struct_def = self.parse_struct()?;
|
let struct_def = self.parse_struct()?;
|
||||||
|
|
@ -221,33 +211,12 @@ impl Parser {
|
||||||
}
|
}
|
||||||
Some(token) => {
|
Some(token) => {
|
||||||
let span = self.peek_span().unwrap_or(start..start);
|
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),
|
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> {
|
fn parse_attribute(&mut self) -> Result<Attribute, ParseError> {
|
||||||
self.expect(Token::At)?;
|
self.expect(Token::At)?;
|
||||||
let start = self.peek_span().unwrap_or(0..0).start;
|
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::KeywordInt, _)) => TypeAnnot::Cons("int".to_string(), vec![]),
|
||||||
Some((Token::KeywordFloat, _)) => TypeAnnot::Cons("float".to_string(), vec![]),
|
Some((Token::KeywordFloat, _)) => TypeAnnot::Cons("float".to_string(), vec![]),
|
||||||
Some((Token::KeywordString, _)) => TypeAnnot::Cons("string".to_string(), vec![]),
|
Some((Token::KeywordString, _)) => TypeAnnot::Cons("string".to_string(), vec![]),
|
||||||
Some((Token::KeywordU8, _)) => TypeAnnot::Cons("u8".to_string(), vec![]),
|
|
||||||
Some((Token::LParen, _)) => {
|
Some((Token::LParen, _)) => {
|
||||||
// Check for unit type: ()
|
// Check for unit type: ()
|
||||||
if matches!(self.peek(), Some(Token::RParen)) {
|
if matches!(self.peek(), Some(Token::RParen)) {
|
||||||
|
|
@ -944,23 +912,8 @@ impl Parser {
|
||||||
}
|
}
|
||||||
Some((Token::LBracket, _)) => {
|
Some((Token::LBracket, _)) => {
|
||||||
let inner = self.parse_type_annot()?;
|
let inner = self.parse_type_annot()?;
|
||||||
if matches!(self.peek(), Some(Token::Semicolon)) {
|
self.expect(Token::RBracket)?;
|
||||||
self.next();
|
TypeAnnot::Array(Box::new(inner))
|
||||||
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))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Some((Token::Bang, _)) => TypeAnnot::Cons("never".to_string(), vec![]),
|
Some((Token::Bang, _)) => TypeAnnot::Cons("never".to_string(), vec![]),
|
||||||
Some((_, span)) => {
|
Some((_, span)) => {
|
||||||
|
|
@ -1204,44 +1157,14 @@ impl Parser {
|
||||||
Ok(left)
|
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> {
|
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 {
|
loop {
|
||||||
if matches!(self.peek(), Some(Token::BitAnd)) {
|
if matches!(self.peek(), Some(Token::BitAnd)) {
|
||||||
let start = left.span.start;
|
let start = left.span.start;
|
||||||
self.next();
|
self.next();
|
||||||
let right = self.parse_shift_expr()?;
|
let right = self.parse_eq_expr()?;
|
||||||
let end = right.span.end;
|
let end = right.span.end;
|
||||||
left = Expr {
|
left = Expr {
|
||||||
kind: ExprKind::BinOp(Box::new(left), BinOp::BitwiseAnd, Box::new(right)),
|
kind: ExprKind::BinOp(Box::new(left), BinOp::BitwiseAnd, Box::new(right)),
|
||||||
|
|
@ -1527,15 +1450,6 @@ impl Parser {
|
||||||
attributes: Vec::new(),
|
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)) => {
|
Some(Token::Float(f)) => {
|
||||||
self.next();
|
self.next();
|
||||||
let end = self.peek_span().unwrap_or(start..start).end;
|
let end = self.peek_span().unwrap_or(start..start).end;
|
||||||
|
|
@ -1693,44 +1607,25 @@ impl Parser {
|
||||||
}
|
}
|
||||||
Some(Token::LBracket) => {
|
Some(Token::LBracket) => {
|
||||||
self.next();
|
self.next();
|
||||||
let first_expr = self.parse_expr()?;
|
let mut elements = Vec::new();
|
||||||
if matches!(self.peek(), Some(Token::Semicolon)) {
|
loop {
|
||||||
self.next();
|
if matches!(self.peek(), Some(Token::RBracket)) {
|
||||||
let size = match self.next() {
|
self.next();
|
||||||
Some((Token::Int(n), _)) => n,
|
break;
|
||||||
Some((_, span)) => {
|
}
|
||||||
return self.error("Expected integer size for fixed array".to_string(), span);
|
elements.push(self.parse_expr()?);
|
||||||
}
|
|
||||||
None => {
|
if matches!(self.peek(), Some(Token::Comma)) {
|
||||||
return self.error("Expected integer size for fixed array".to_string(), start..start);
|
self.next();
|
||||||
}
|
|
||||||
};
|
|
||||||
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 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) => {
|
Some(Token::KeywordLet) => {
|
||||||
self.next();
|
self.next();
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,12 @@ use std::fmt;
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Type {
|
pub enum Type {
|
||||||
Int,
|
Int,
|
||||||
U8,
|
|
||||||
Float,
|
Float,
|
||||||
Bool,
|
Bool,
|
||||||
String,
|
String,
|
||||||
Unit,
|
Unit,
|
||||||
Never,
|
Never,
|
||||||
Array(Box<Type>),
|
Array(Box<Type>),
|
||||||
FixedArray(Box<Type>, usize),
|
|
||||||
Ptr(Box<Type>),
|
Ptr(Box<Type>),
|
||||||
Tuple(Vec<Type>),
|
Tuple(Vec<Type>),
|
||||||
Function(Vec<Type>, Box<Type>),
|
Function(Vec<Type>, Box<Type>),
|
||||||
|
|
@ -28,14 +26,12 @@ impl Type {
|
||||||
pub fn to_string(&self) -> String {
|
pub fn to_string(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
Type::Int => "int".to_string(),
|
Type::Int => "int".to_string(),
|
||||||
Type::U8 => "u8".to_string(),
|
|
||||||
Type::Float => "float".to_string(),
|
Type::Float => "float".to_string(),
|
||||||
Type::Bool => "bool".to_string(),
|
Type::Bool => "bool".to_string(),
|
||||||
Type::String => "string".to_string(),
|
Type::String => "string".to_string(),
|
||||||
Type::Unit => "()".to_string(),
|
Type::Unit => "()".to_string(),
|
||||||
Type::Never => "!".to_string(),
|
Type::Never => "!".to_string(),
|
||||||
Type::Array(inner) => format!("[{}]", inner.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::Ptr(inner) => format!("*{}", inner.to_string()),
|
||||||
Type::Tuple(types) => {
|
Type::Tuple(types) => {
|
||||||
let type_strs: Vec<String> = types.iter().map(|t| t.to_string()).collect();
|
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) {
|
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
|
// ODE Physics Engine functions
|
||||||
self.env.functions.insert(
|
self.env.functions.insert(
|
||||||
"ode_init".to_string(),
|
"ode_init".to_string(),
|
||||||
|
|
@ -1909,19 +1560,6 @@ impl TypeChecker {
|
||||||
|
|
||||||
fn typecheck_node(&mut self, node: &ASTNode) -> Result<TypedASTNode, TypeError> {
|
fn typecheck_node(&mut self, node: &ASTNode) -> Result<TypedASTNode, TypeError> {
|
||||||
let ty = match &node.kind {
|
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) => {
|
ASTNodeKind::Function(f) => {
|
||||||
let typed_func = self.typecheck_function(f)?;
|
let typed_func = self.typecheck_function(f)?;
|
||||||
let ty = typed_func.ty.clone();
|
let ty = typed_func.ty.clone();
|
||||||
|
|
@ -2123,16 +1761,6 @@ impl TypeChecker {
|
||||||
fn typecheck_expr(&mut self, expr: &Expr) -> Result<TypedExpr, TypeError> {
|
fn typecheck_expr(&mut self, expr: &Expr) -> Result<TypedExpr, TypeError> {
|
||||||
let (kind, ty) = match &expr.kind {
|
let (kind, ty) = match &expr.kind {
|
||||||
ExprKind::Int(n) => (TypedExprKind::Int(*n), Type::Int),
|
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::Float(f) => (TypedExprKind::Float(*f), Type::Float),
|
||||||
ExprKind::Bool(b) => (TypedExprKind::Bool(*b), Type::Bool),
|
ExprKind::Bool(b) => (TypedExprKind::Bool(*b), Type::Bool),
|
||||||
ExprKind::String(s) => (TypedExprKind::String(s.clone()), Type::String),
|
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) => {
|
ExprKind::Tuple(elements) => {
|
||||||
let mut typed_elements = Vec::new();
|
let mut typed_elements = Vec::new();
|
||||||
let mut types = Vec::new();
|
let mut types = Vec::new();
|
||||||
|
|
@ -2220,7 +1840,7 @@ impl TypeChecker {
|
||||||
let typed_right = self.typecheck_expr(right)?;
|
let typed_right = self.typecheck_expr(right)?;
|
||||||
|
|
||||||
let result_type = match op {
|
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) {
|
if !self.types_compatible(&typed_left.ty, &typed_right.ty) {
|
||||||
return Err(TypeError {
|
return Err(TypeError {
|
||||||
kind: TypeErrorKind::TypeMismatch(
|
kind: TypeErrorKind::TypeMismatch(
|
||||||
|
|
@ -2551,7 +2171,7 @@ impl TypeChecker {
|
||||||
}
|
}
|
||||||
|
|
||||||
let element_type = match &typed_array.ty {
|
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 => {
|
ty => {
|
||||||
return Err(TypeError {
|
return Err(TypeError {
|
||||||
kind: TypeErrorKind::NotAnArray(ty.clone()),
|
kind: TypeErrorKind::NotAnArray(ty.clone()),
|
||||||
|
|
@ -3216,14 +2836,13 @@ impl TypeChecker {
|
||||||
TypeInfoKind::Enum(_) => Type::Enum(name.clone(), substituted_args),
|
TypeInfoKind::Enum(_) => Type::Enum(name.clone(), substituted_args),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match name.as_str() {
|
match name.as_str() {
|
||||||
"int" => Type::Int,
|
"int" => Type::Int,
|
||||||
"u8" => Type::U8,
|
"float" => Type::Float,
|
||||||
"float" => Type::Float,
|
"bool" => Type::Bool,
|
||||||
"bool" => Type::Bool,
|
"string" => Type::String,
|
||||||
"string" => Type::String,
|
"unit" => Type::Unit,
|
||||||
"unit" => Type::Unit,
|
"never" => Type::Never,
|
||||||
"never" => Type::Never,
|
|
||||||
_ => Type::Generic(name.clone(), substituted_args),
|
_ => Type::Generic(name.clone(), substituted_args),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3231,9 +2850,6 @@ impl TypeChecker {
|
||||||
TypeAnnot::Array(inner) => {
|
TypeAnnot::Array(inner) => {
|
||||||
Type::Array(Box::new(self.substitute_type(inner, subst_map)))
|
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::Ptr(inner) => Type::Ptr(Box::new(self.substitute_type(inner, subst_map))),
|
||||||
TypeAnnot::Tuple(types) => {
|
TypeAnnot::Tuple(types) => {
|
||||||
let substituted_types: Vec<Type> = types
|
let substituted_types: Vec<Type> = types
|
||||||
|
|
@ -3277,7 +2893,6 @@ impl TypeChecker {
|
||||||
|
|
||||||
match name.as_str() {
|
match name.as_str() {
|
||||||
"int" => Type::Int,
|
"int" => Type::Int,
|
||||||
"u8" => Type::U8,
|
|
||||||
"float" => Type::Float,
|
"float" => Type::Float,
|
||||||
"bool" => Type::Bool,
|
"bool" => Type::Bool,
|
||||||
"string" => Type::String,
|
"string" => Type::String,
|
||||||
|
|
@ -3308,7 +2923,6 @@ impl TypeChecker {
|
||||||
Type::Tuple(tuple_types)
|
Type::Tuple(tuple_types)
|
||||||
}
|
}
|
||||||
TypeAnnot::Array(inner) => Type::Array(Box::new(self.type_annot_to_type(inner))),
|
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))),
|
TypeAnnot::Ptr(inner) => Type::Ptr(Box::new(self.type_annot_to_type(inner))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3317,14 +2931,12 @@ impl TypeChecker {
|
||||||
match (t1, t2) {
|
match (t1, t2) {
|
||||||
(Type::Unknown, _) | (_, Type::Unknown) => true,
|
(Type::Unknown, _) | (_, Type::Unknown) => true,
|
||||||
(Type::Int, Type::Int) => true,
|
(Type::Int, Type::Int) => true,
|
||||||
(Type::U8, Type::U8) => true,
|
|
||||||
(Type::Float, Type::Float) => true,
|
(Type::Float, Type::Float) => true,
|
||||||
(Type::Bool, Type::Bool) => true,
|
(Type::Bool, Type::Bool) => true,
|
||||||
(Type::String, Type::String) => true,
|
(Type::String, Type::String) => true,
|
||||||
(Type::Unit, Type::Unit) => true,
|
(Type::Unit, Type::Unit) => true,
|
||||||
(Type::Never, _) | (_, Type::Never) => true,
|
(Type::Never, _) | (_, Type::Never) => true,
|
||||||
(Type::Array(a), Type::Array(b)) => self.types_compatible(a, b),
|
(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::Ptr(a), Type::Ptr(b)) => self.types_compatible(a, b),
|
||||||
(Type::Tuple(a), Type::Tuple(b)) => {
|
(Type::Tuple(a), Type::Tuple(b)) => {
|
||||||
a.len() == b.len()
|
a.len() == b.len()
|
||||||
|
|
|
||||||
|
|
@ -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.
|
|
@ -1,6 +0,0 @@
|
||||||
# Fixed array test
|
|
||||||
fn main() -> int do
|
|
||||||
let arr: [int; 5] = [42; 5];
|
|
||||||
let x = arr[2];
|
|
||||||
x
|
|
||||||
end
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue