Body parsing

This commit is contained in:
2026-04-14 03:22:35 +02:00
parent 2aef4c20be
commit 9ced12933a
4 changed files with 51 additions and 9 deletions
+5 -2
View File
@@ -20,14 +20,14 @@ pub enum TopLevel {
name: String, name: String,
params: ParamList, params: ParamList,
return_type: Option<TypeExpr>, return_type: Option<TypeExpr>,
body: Vec<Statement>, body: Block,
}, },
} }
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
#[serde(tag = "type", content = "value")] #[serde(tag = "type", content = "value")]
pub enum Statement { pub enum Statement {
Expression(String), Expression(Expression),
} }
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
@@ -46,3 +46,6 @@ pub enum Expression {
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
pub struct ParamList(pub Vec<(String, TypeExpr)>); pub struct ParamList(pub Vec<(String, TypeExpr)>);
#[derive(Debug, Clone, Serialize)]
pub struct Block(pub Vec<Statement>);
+4 -4
View File
@@ -15,7 +15,7 @@ inner_str = @{ (!"\"" ~ ANY)* }
top_level = _{ import | function_decl | struct_decl } top_level = _{ import | function_decl | struct_decl }
export = { "export"? } export = { "export" }
import = { "import" ~ string_lit ~ ";" } import = { "import" ~ string_lit ~ ";" }
@@ -23,11 +23,11 @@ param_list = { param ~ ("," ~ param)* ~ ","? }
param = { identifier ~ ":" ~ type_expr } param = { identifier ~ ":" ~ type_expr }
struct_decl = { struct_decl = {
export ~ "struct" ~ identifier ~ "{" ~ param_list? ~ "}" export? ~ "struct" ~ identifier ~ "{" ~ param_list? ~ "}"
} }
function_decl = { function_decl = {
export ~ "function" ~ identifier ~ "(" ~ param_list? ~ ")" ~ (":" ~ type_expr)? ~ block export? ~ "function" ~ identifier ~ "(" ~ param_list? ~ ")" ~ (":" ~ type_expr)? ~ block
} }
// ================= STATEMENTS ================= // ================= STATEMENTS =================
@@ -41,6 +41,6 @@ statement = _{ expr_stmt }
expr_stmt = { expr ~ ";" } expr_stmt = { expr ~ ";" }
// ================= EXPRESSIONS ================= // ================= EXPRESSIONS =================
type_expr = _{ identifier } type_expr = { identifier }
expr = { identifier | integer | float | boolean | string_lit } expr = { identifier | integer | float | boolean | string_lit }
+39 -2
View File
@@ -63,6 +63,7 @@ impl TopLevel {
} }
Rule::function_decl => { Rule::function_decl => {
let mut inner = pair.into_inner(); let mut inner = pair.into_inner();
let export = if let Some(first) = inner.peek() { let export = if let Some(first) = inner.peek() {
if first.as_rule() == Rule::export { if first.as_rule() == Rule::export {
inner.next(); inner.next();
@@ -90,13 +91,14 @@ impl TopLevel {
None None
}; };
// For now, we'll just ignore the function body and return an empty vector let body = Block::from_pair(inner.next().unwrap());
Some(TopLevel::FunctionDecl { Some(TopLevel::FunctionDecl {
export, export,
name, name,
params, params,
return_type, return_type,
body: vec![], body,
}) })
} }
@@ -129,6 +131,41 @@ impl TopLevel {
} }
} }
impl Block {
pub fn from_pair(pair: pest::iterators::Pair<Rule>) -> Self {
let statements = pair
.into_inner()
.flat_map(|pair| {
if pair.as_rule() == Rule::statement_list {
pair.into_inner().map(Statement::from_pair).collect()
} else {
vec![Statement::from_pair(pair)]
}
})
.collect();
Block(statements)
}
}
impl Statement {
pub fn from_pair(pair: pest::iterators::Pair<Rule>) -> Self {
match pair.as_rule() {
Rule::statement => {
let inner = pair.into_inner().next().unwrap();
Statement::from_pair(inner)
}
Rule::expr_stmt => {
let expr_pair = pair.into_inner().next().unwrap();
Statement::Expression(Expression::from_pair(expr_pair))
}
_ => unimplemented!(
"Statement parsing not implemented yet: {:?}",
pair.as_rule()
),
}
}
}
impl Expression { impl Expression {
pub fn from_pair(pair: pest::iterators::Pair<Rule>) -> Self { pub fn from_pair(pair: pest::iterators::Pair<Rule>) -> Self {
match pair.as_rule() { match pair.as_rule() {
+3 -1
View File
@@ -5,4 +5,6 @@ struct Point {
y: int y: int
} }
function add(a: int, b: int): int {} function add(a: int, b: int): int {
do_something;
}