Ifs and Phis
This commit is contained in:
+28
-12
@@ -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
@@ -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})*
|
||||
|
||||
Reference in New Issue
Block a user