Statements
This commit is contained in:
+63
-8
@@ -1,5 +1,11 @@
|
|||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
pub struct ParamList(pub Vec<(String, TypeExpr)>);
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
pub struct Block(pub Vec<Statement>);
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
#[serde(tag = "type", content = "value")]
|
#[serde(tag = "type", content = "value")]
|
||||||
pub enum TypeExpr {
|
pub enum TypeExpr {
|
||||||
@@ -24,10 +30,55 @@ pub enum TopLevel {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
#[serde(tag = "type", content = "value")]
|
||||||
|
pub enum Postfix {
|
||||||
|
FieldAccess(String),
|
||||||
|
FunctionCall(Vec<Expression>),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
#[serde(tag = "type", content = "value")]
|
#[serde(tag = "type", content = "value")]
|
||||||
pub enum Statement {
|
pub enum Statement {
|
||||||
|
// expr;
|
||||||
Expression(Expression),
|
Expression(Expression),
|
||||||
|
|
||||||
|
// { ... }
|
||||||
|
Block(Block),
|
||||||
|
|
||||||
|
// let/const/var x = ...
|
||||||
|
VarDecl {
|
||||||
|
kind: VarKind,
|
||||||
|
name: String,
|
||||||
|
init: Option<Expression>,
|
||||||
|
},
|
||||||
|
|
||||||
|
// if (...) stmt else stmt
|
||||||
|
If {
|
||||||
|
condition: Expression,
|
||||||
|
then_branch: Box<Statement>,
|
||||||
|
else_branch: Option<Box<Statement>>,
|
||||||
|
},
|
||||||
|
|
||||||
|
// while (...) stmt
|
||||||
|
While {
|
||||||
|
condition: Expression,
|
||||||
|
body: Box<Statement>,
|
||||||
|
},
|
||||||
|
|
||||||
|
// for (...) stmt
|
||||||
|
For {
|
||||||
|
init: Option<ForInit>,
|
||||||
|
condition: Option<Expression>,
|
||||||
|
update: Option<Expression>,
|
||||||
|
body: Box<Statement>,
|
||||||
|
},
|
||||||
|
|
||||||
|
// return expr?;
|
||||||
|
Return(Option<Expression>),
|
||||||
|
|
||||||
|
Break,
|
||||||
|
Continue,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
@@ -45,14 +96,18 @@ pub enum Expression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
#[serde(tag = "type", content = "value")]
|
pub enum VarKind {
|
||||||
pub enum Postfix {
|
Let,
|
||||||
FieldAccess(String),
|
Const,
|
||||||
FunctionCall(Vec<Expression>),
|
Var,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
pub struct ParamList(pub Vec<(String, TypeExpr)>);
|
pub enum ForInit {
|
||||||
|
VarDecl {
|
||||||
#[derive(Debug, Clone, Serialize)]
|
kind: VarKind,
|
||||||
pub struct Block(pub Vec<Statement>);
|
name: String,
|
||||||
|
init: Option<Expression>,
|
||||||
|
},
|
||||||
|
Expr(Expression),
|
||||||
|
}
|
||||||
|
|||||||
+47
-1
@@ -36,10 +36,56 @@ block = { "{" ~ statement_list ~ "}" }
|
|||||||
|
|
||||||
statement_list = { statement* }
|
statement_list = { statement* }
|
||||||
|
|
||||||
statement = _{ expr_stmt }
|
statement = _{
|
||||||
|
expr_stmt
|
||||||
|
| var_decl
|
||||||
|
| if_stmt
|
||||||
|
| while_stmt
|
||||||
|
| for_stmt
|
||||||
|
| return_stmt
|
||||||
|
| break_stmt
|
||||||
|
| continue_stmt
|
||||||
|
| block
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- basic statements ---
|
||||||
|
|
||||||
expr_stmt = { expr ~ ";" }
|
expr_stmt = { expr ~ ";" }
|
||||||
|
|
||||||
|
return_stmt = { "return" ~ expr? ~ ";" }
|
||||||
|
|
||||||
|
break_stmt = { "break" ~ ";" }
|
||||||
|
|
||||||
|
continue_stmt = { "continue" ~ ";" }
|
||||||
|
|
||||||
|
// --- variable declarations ---
|
||||||
|
|
||||||
|
var_decl = {
|
||||||
|
("let" | "const" | "var") ~ identifier ~ ("=" ~ expr)? ~ ";"
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- control flow ---
|
||||||
|
|
||||||
|
if_stmt = {
|
||||||
|
"if" ~ "(" ~ expr ~ ")" ~ statement ~ ("else" ~ statement)?
|
||||||
|
}
|
||||||
|
|
||||||
|
while_stmt = {
|
||||||
|
"while" ~ "(" ~ expr ~ ")" ~ statement
|
||||||
|
}
|
||||||
|
|
||||||
|
for_stmt = {
|
||||||
|
"for" ~ "(" ~ (var_decl_no_semicolon | expr_stmt | ";")
|
||||||
|
~ expr? ~ ";"
|
||||||
|
~ expr? ~ ")"
|
||||||
|
~ statement
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper (same as var_decl but no trailing ;)
|
||||||
|
var_decl_no_semicolon = {
|
||||||
|
("let" | "const" | "var") ~ identifier ~ ("=" ~ expr)?
|
||||||
|
}
|
||||||
|
|
||||||
// ================= EXPRESSIONS =================
|
// ================= EXPRESSIONS =================
|
||||||
type_expr = { identifier }
|
type_expr = { identifier }
|
||||||
|
|
||||||
|
|||||||
@@ -154,10 +154,118 @@ impl Statement {
|
|||||||
let inner = pair.into_inner().next().unwrap();
|
let inner = pair.into_inner().next().unwrap();
|
||||||
Statement::from_pair(inner)
|
Statement::from_pair(inner)
|
||||||
}
|
}
|
||||||
|
|
||||||
Rule::expr_stmt => {
|
Rule::expr_stmt => {
|
||||||
let expr_pair = pair.into_inner().next().unwrap();
|
let expr_pair = pair.into_inner().next().unwrap();
|
||||||
Statement::Expression(Expression::from_pair(expr_pair))
|
Statement::Expression(Expression::from_pair(expr_pair))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rule::block => Statement::Block(Block::from_pair(pair.into_inner().next().unwrap())),
|
||||||
|
|
||||||
|
Rule::var_decl => {
|
||||||
|
let mut inner = pair.into_inner();
|
||||||
|
|
||||||
|
let kind_pair = inner.next().unwrap(); // let/const/var
|
||||||
|
let name_pair = inner.next().unwrap(); // identifier
|
||||||
|
|
||||||
|
let init = inner.next().map(|expr_pair| {
|
||||||
|
// expects "=" expr
|
||||||
|
Expression::from_pair(expr_pair.into_inner().next().unwrap())
|
||||||
|
});
|
||||||
|
|
||||||
|
let kind = match kind_pair.as_str() {
|
||||||
|
"let" => VarKind::Let,
|
||||||
|
"const" => VarKind::Const,
|
||||||
|
"var" => VarKind::Var,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Statement::VarDecl {
|
||||||
|
kind,
|
||||||
|
name: name_pair.as_str().to_string(),
|
||||||
|
init,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rule::return_stmt => {
|
||||||
|
let mut inner = pair.into_inner();
|
||||||
|
|
||||||
|
let expr = inner.next().map(Expression::from_pair);
|
||||||
|
|
||||||
|
Statement::Return(expr)
|
||||||
|
}
|
||||||
|
|
||||||
|
Rule::break_stmt => Statement::Break,
|
||||||
|
|
||||||
|
Rule::continue_stmt => Statement::Continue,
|
||||||
|
|
||||||
|
Rule::if_stmt => {
|
||||||
|
let mut inner = pair.into_inner();
|
||||||
|
|
||||||
|
let condition = Expression::from_pair(inner.next().unwrap());
|
||||||
|
let then_branch = Statement::from_pair(inner.next().unwrap());
|
||||||
|
|
||||||
|
let else_branch = inner.next().map(Statement::from_pair);
|
||||||
|
|
||||||
|
Statement::If {
|
||||||
|
condition,
|
||||||
|
then_branch: Box::new(then_branch),
|
||||||
|
else_branch: else_branch.map(Box::new),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rule::while_stmt => {
|
||||||
|
let mut inner = pair.into_inner();
|
||||||
|
|
||||||
|
let condition = Expression::from_pair(inner.next().unwrap());
|
||||||
|
let body = Statement::from_pair(inner.next().unwrap());
|
||||||
|
|
||||||
|
Statement::While {
|
||||||
|
condition,
|
||||||
|
body: Box::new(body),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rule::for_stmt => {
|
||||||
|
let mut inner = pair.into_inner();
|
||||||
|
|
||||||
|
let init = inner.next().map(|p| match p.as_rule() {
|
||||||
|
Rule::var_decl_no_semicolon => {
|
||||||
|
let mut it = p.into_inner();
|
||||||
|
|
||||||
|
let kind = match it.next().unwrap().as_str() {
|
||||||
|
"let" => VarKind::Let,
|
||||||
|
"const" => VarKind::Const,
|
||||||
|
"var" => VarKind::Var,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let name = it.next().unwrap().as_str().to_string();
|
||||||
|
let init_expr = it
|
||||||
|
.next()
|
||||||
|
.map(|e| Expression::from_pair(e.into_inner().next().unwrap()));
|
||||||
|
|
||||||
|
ForInit::VarDecl {
|
||||||
|
kind,
|
||||||
|
name,
|
||||||
|
init: init_expr,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => ForInit::Expr(Expression::from_pair(p)),
|
||||||
|
});
|
||||||
|
|
||||||
|
let condition = inner.next().map(Expression::from_pair);
|
||||||
|
let update = inner.next().map(Expression::from_pair);
|
||||||
|
let body = Statement::from_pair(inner.next().unwrap());
|
||||||
|
|
||||||
|
Statement::For {
|
||||||
|
init,
|
||||||
|
condition,
|
||||||
|
update,
|
||||||
|
body: Box::new(body),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_ => unimplemented!(
|
_ => unimplemented!(
|
||||||
"Statement parsing not implemented yet: {:?}",
|
"Statement parsing not implemented yet: {:?}",
|
||||||
pair.as_rule()
|
pair.as_rule()
|
||||||
|
|||||||
+3
-1
@@ -6,5 +6,7 @@ struct Point {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function add(a: int, b: int): int {
|
function add(a: int, b: int): int {
|
||||||
idk.do_something(123, "abc");
|
if (x) {
|
||||||
|
if (y) return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user