Ifs and Phis

This commit is contained in:
Mia
2026-03-07 16:24:32 +01:00
parent fb84e09391
commit 168a12b4fc
11 changed files with 612 additions and 150 deletions
+28 -12
View File
@@ -26,30 +26,33 @@ pub enum Expr {
Number(Number),
String(Substr),
#[debug("{_0:?}")]
Binary(Arc<BinaryExpr>),
Index(Arc<IndexingExpr>),
Access(Arc<AccessExpr>),
Binary(Box<BinaryExpr>),
Index(Box<IndexingExpr>),
Access(Box<AccessExpr>),
Deref(Box<Expr>),
Tuple(Vec<Expr>),
List(Vec<Expr>),
Struct(Arc<StructCtor>),
Struct(Box<StructCtor>),
#[debug("{_0:?}")]
Block(Block),
Block(Arc<Block>),
#[debug("{_0:?}")]
Func(Arc<Function>),
#[debug("{_0:?}")]
Type(Arc<Type>),
Type(Box<Type>),
#[debug("{_0:?}")]
ConstDecl(Arc<ConstDecl>),
ConstDecl(Box<ConstDecl>),
#[debug("{_0:?}")]
VarDecl(Arc<VarDecl>),
VarDecl(Box<VarDecl>),
#[debug("{_0:?}")]
For(Arc<For>),
For(Box<For>),
#[debug("{_0:?}")]
While(Arc<While>),
While(Box<While>),
#[debug("{_0:?}")]
If(Box<If>),
Call {
func: Arc<Expr>,
func: Box<Expr>,
args: Vec<Expr>,
},
}
@@ -191,10 +194,23 @@ pub struct For {
#[derive(Debug)]
pub struct While {
pub value: Expr,
pub cond: Expr,
pub block: Block,
}
#[derive(Debug)]
pub struct If {
pub cond: Expr,
pub block: Block,
pub else_: Option<Box<Else>>,
}
#[derive(Debug)]
pub enum Else {
If(If),
Block(Block),
}
#[derive(Debug)]
pub struct CompilationUnit {
pub imports: Vec<Import>,
+40 -29
View File
@@ -73,44 +73,48 @@ peg::parser! {
// ### EXPRESSIONS ####
rule expr() -> Expr = precedence! {
lhs:(@) __ op:$("as") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Cast(op), rhs })) }
lhs:(@) __ op:$("as") __ rhs:expr() { Expr::Binary(BinaryExpr { lhs, op: BinaryOp::Cast(op), rhs }.into()) }
--
lhs:@ __ op:$("=") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Assign(op), rhs })) }
lhs:@ __ op:$("=") __ rhs:expr() { Expr::Binary(BinaryExpr { lhs, op: BinaryOp::Assign(op), rhs }.into()) }
value:@ __ op:$(".") __ field:ident2() { Expr::Access(AccessExpr { value, field }.into()) }
lhs:@ "(" __ args:(expr() ** list_separator()) __ ")" { Expr::Call { func: Arc::new(lhs), args } }
value:@ "[" __ index:expr() __ "]" { Expr::Index(Arc::new(IndexingExpr { value, index })) }
value:@ __ op:$(".^") { Expr::Deref(value.into()) }
lhs:@ "(" __ args:(expr() ** list_separator()) __ ")" { Expr::Call { func: lhs.into(), args } }
value:@ "[" __ index:expr() __ "]" { Expr::Index(IndexingExpr { value, index }.into()) }
r#type:@ __ "{" __ values:name_value_pairs() __ "}" { Expr::Struct(Arc::new(StructCtor {
r#type, values: values.into_iter().map(|v| (v.name.0.clone(), v)).collect()
})) }
r#type:@ __ "#{" __ values:name_value_pairs() __ "}" { Expr::Struct(
StructCtor {
r#type, values: values.into_iter().map(|v| (v.name.0.clone(), v)).collect()
}.into()
) }
--
lhs:@ __ op:$("+") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Add(op), rhs })) }
lhs:@ __ op:$("-") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Sub(op), rhs })) }
lhs:@ __ op:$("+") __ rhs:expr() { Expr::Binary(BinaryExpr { lhs, op: BinaryOp::Add(op), rhs }.into()) }
lhs:@ __ op:$("-") __ rhs:expr() { Expr::Binary(BinaryExpr { lhs, op: BinaryOp::Sub(op), rhs }.into()) }
--
lhs:@ __ op:$("*") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Mul(op), rhs })) }
lhs:@ __ op:$("/") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Div(op), rhs })) }
lhs:@ __ op:$("%") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Mod(op), rhs })) }
lhs:@ __ op:$("*") __ rhs:expr() { Expr::Binary(BinaryExpr { lhs, op: BinaryOp::Mul(op), rhs }.into()) }
lhs:@ __ op:$("/") __ rhs:expr() { Expr::Binary(BinaryExpr { lhs, op: BinaryOp::Div(op), rhs }.into()) }
lhs:@ __ op:$("%") __ rhs:expr() { Expr::Binary(BinaryExpr { lhs, op: BinaryOp::Mod(op), rhs }.into()) }
--
lhs:@ __ op:$("..") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Range(op), rhs })) }
lhs:@ __ op:$("..") __ rhs:expr() { Expr::Binary(BinaryExpr { lhs, op: BinaryOp::Range(op), rhs }.into()) }
--
lhs:@ __ op:$("==") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Eq(op), rhs })) }
lhs:@ __ op:$("!=") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Ne(op), rhs })) }
lhs:@ __ op:$("<") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Lt(op), rhs })) }
lhs:@ __ op:$(">") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Gt(op), rhs })) }
lhs:@ __ op:$("<=") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Le(op), rhs })) }
lhs:@ __ op:$(">=") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Ge(op), rhs })) }
lhs:@ __ op:$("==") __ rhs:expr() { Expr::Binary(BinaryExpr { lhs, op: BinaryOp::Eq(op), rhs }.into()) }
lhs:@ __ op:$("!=") __ rhs:expr() { Expr::Binary(BinaryExpr { lhs, op: BinaryOp::Ne(op), rhs }.into()) }
lhs:@ __ op:$("<") __ rhs:expr() { Expr::Binary(BinaryExpr { lhs, op: BinaryOp::Lt(op), rhs }.into()) }
lhs:@ __ op:$(">") __ rhs:expr() { Expr::Binary(BinaryExpr { lhs, op: BinaryOp::Gt(op), rhs }.into()) }
lhs:@ __ op:$("<=") __ rhs:expr() { Expr::Binary(BinaryExpr { lhs, op: BinaryOp::Le(op), rhs }.into()) }
lhs:@ __ op:$(">=") __ rhs:expr() { Expr::Binary(BinaryExpr { lhs, op: BinaryOp::Ge(op), rhs }.into()) }
--
block:block() { Expr::Block(block)}
for_loop:for_loop() { Expr::For(Arc::new(for_loop))}
while_loop:while_loop() { Expr::While(Arc::new(while_loop))}
block:block() { Expr::Block(block.into())}
for_loop:for_loop() { Expr::For(for_loop.into())}
while_loop:while_loop() { Expr::While(while_loop.into())}
if_statement:if_statement() { Expr::If(if_statement.into())}
func:func() { Expr::Func(Arc::new(func))}
var_decl:var_decl() { Expr::VarDecl(Arc::new(var_decl)) }
const_decl:const_decl() { Expr::ConstDecl(Arc::new(const_decl)) }
var_decl:var_decl() { Expr::VarDecl(var_decl.into()) }
const_decl:const_decl() { Expr::ConstDecl(const_decl.into()) }
"(" __ tuple:(expr() **<2,> ("," __)) __ ")" { Expr::Tuple(tuple) }
"[" __ list:(expr() ** ("," __)) __ "]" { Expr::List(list) }
"(" __ v:expr() __ ")" { v }
"*" __ m:$"mut"? __ v:expr() { Expr::Type(Arc::new(Type::Ptr { base:v, mutable: m })) }
v:struct_t() { Expr::Type(Arc::new(Type::Struct(v))) }
"*" __ m:$"mut"? __ v:expr() { Expr::Type(Type::Ptr { base:v, mutable: m }.into()) }
v:struct_t() { Expr::Type(Type::Struct(v).into()) }
v:string() { Expr::String(v) }
v:number() { Expr::Number(v) }
v:ident() { Expr::Ident(v) }
@@ -121,7 +125,7 @@ peg::parser! {
rule func() -> Function
= s:position!() t:$"fn" __ "(" __ args:name_type_pairs() __ ")" __ ret:("->" __ e:expr() {e})? __ block:block()? e:position!()
{ Function { args, ret, block: block.map(Arc::new), text: t.parent().substr(s..e), } }
{ Function { args, ret, block: block.map(Into::into), text: t.parent().substr(s..e), } }
rule name_type_pair() -> NameValuePair
= name:ident() __ ":" __ value:expr() { NameValuePair { name, value } }
@@ -168,8 +172,15 @@ peg::parser! {
{ For { names, value, block } }
rule while_loop() -> While =
"while" _ value:expr() _ block:block()
{ While { value, block } }
"while" _ cond:expr() _ block:block()
{ While { cond, block } }
rule if_statement() -> If =
"if" _ cond:expr() __ block:block() e:(__ e:else_statement() {e})? { If { cond, block, else_: e.map(Box::new) } }
rule else_statement() -> Else
= "else" _ i:if_statement() { Else::If(i) }
/ "else" __ b:block() { Else::Block(b) }
pub rule compilation_unit() -> CompilationUnit =
__ imports:(i:import() statement_separator() {i})*