Merge pull request #16 from mist-go/updated-grammar-ast

Updated grammar and AST
This commit is contained in:
2026-05-02 17:23:20 +02:00
committed by GitHub
5 changed files with 83 additions and 143 deletions
+40 -38
View File
@@ -56,53 +56,55 @@ pub enum Postfix {
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
pub enum Statement { pub enum Statement {
// expr;
Expression(Expression), Expression(Expression),
// { ... }
Block(Block), Block(Block),
// let/const/var x = ... VarDecl(VarDeclStmt),
VarDecl { VarAssign(VarAssignStmt),
mutable: bool, If(IfStmt),
name: String, While(WhileStmt),
init: Option<Expression>, For(ForStmt),
type_: Option<TypeExpr>,
},
VarAssign {
target: Expression,
value: 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: (bool, String, Option<Expression>),
condition: Option<Expression>,
update: Option<Box<Statement>>,
body: Box<Statement>,
},
// return expr?;
Return(Option<Expression>), Return(Option<Expression>),
Break, Break,
Continue, Continue,
} }
#[derive(Debug, Clone, Serialize)]
pub struct VarDeclStmt {
pub mutable: bool,
pub name: String,
pub init: Option<Expression>,
pub type_: Option<TypeExpr>,
}
#[derive(Debug, Clone, Serialize)]
pub struct VarAssignStmt {
pub target: Expression,
pub value: Expression,
}
#[derive(Debug, Clone, Serialize)]
pub struct IfStmt {
pub condition: Expression,
pub then_branch: Box<Statement>,
pub else_branch: Option<Box<Statement>>,
}
#[derive(Debug, Clone, Serialize)]
pub struct WhileStmt {
pub condition: Expression,
pub body: Box<Statement>,
}
#[derive(Debug, Clone, Serialize)]
pub struct ForStmt {
pub init: (bool, String, Option<Expression>),
pub condition: Option<Expression>,
pub update: Option<Box<Statement>>,
pub body: Box<Statement>,
}
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
pub enum Expression { pub enum Expression {
Identifier(String), Identifier(String),
+11 -29
View File
@@ -11,19 +11,23 @@ boolean = { "true" | "false" }
string_lit = { "\"" ~ inner_str ~ "\"" } string_lit = { "\"" ~ inner_str ~ "\"" }
inner_str = @{ (!"\"" ~ ANY)* } inner_str = @{ (!"\"" ~ ANY)* }
export = { "public" }
mutable = { "mut" }
var_decl = { type_expr ~ mutable? ~ identifier }
// ================= TOP LEVEL ================= // ================= TOP LEVEL =================
top_level = _{ import | function_decl | struct_decl } top_level = _{ import | function_decl | struct_decl }
export = { "public" }
import = { "import" ~ string_lit ~ ";" } import = { "import" ~ string_lit ~ ";" }
param_list = { param ~ ("," ~ param)* ~ ","? } field_list = { field ~ ("," ~ field)* ~ ","? }
param = { export? ~ type_expr ~ identifier } field = { export? ~ type_expr ~ identifier }
param_list = { var_decl ~ ("," ~ var_decl)* ~ ","? }
struct_decl = { struct_decl = {
export? ~ "struct" ~ identifier ~ "{" ~ param_list? ~ "}" export? ~ "struct" ~ identifier ~ "{" ~ field_list? ~ "}"
} }
function_decl = { function_decl = {
@@ -38,11 +42,9 @@ statement_list = { statement* }
statement = _{ statement = _{
expr_stmt expr_stmt
| var_decl | var_decl_statement
| var_assign
| if_stmt | if_stmt
| while_stmt | while_stmt
| for_stmt
| return_stmt | return_stmt
| break_stmt | break_stmt
| continue_stmt | continue_stmt
@@ -59,19 +61,7 @@ break_stmt = { "break" ~ ";" }
continue_stmt = { "continue" ~ ";" } continue_stmt = { "continue" ~ ";" }
// --- variable declarations --- var_decl_statement = { var_decl ~ ("=" ~ expr)? ~ ";" }
// var_decl_kind = { "let" | "const" | "var" }
var_decl = {
type_expr ~ identifier ~ ("=" ~ expr)? ~ ";"
}
var_assign = {
expr ~ "=" ~ expr ~ ";"
}
// --- control flow ---
if_stmt = { if_stmt = {
"if" ~ "(" ~ expr ~ ")" ~ statement ~ ("else" ~ statement)? "if" ~ "(" ~ expr ~ ")" ~ statement ~ ("else" ~ statement)?
@@ -81,14 +71,6 @@ while_stmt = {
"while" ~ "(" ~ expr ~ ")" ~ statement "while" ~ "(" ~ expr ~ ")" ~ statement
} }
for_stmt = {
"for" ~ "(" ~ var_decl ~ expr ~ ";" ~ var_assign_no_semicolon ~ ")" ~ statement
}
var_assign_no_semicolon = {
expr ~ "=" ~ expr
}
// ================= EXPRESSIONS ================= // ================= EXPRESSIONS =================
type_expr = { identifier } type_expr = { identifier }
+20 -61
View File
@@ -17,6 +17,8 @@ pub type ParseError = pest::error::Error<Rule>;
pub fn parse(source: &str) -> Result<Vec<TopLevel>, ParseError> { pub fn parse(source: &str) -> Result<Vec<TopLevel>, ParseError> {
let mut pairs = MistParser::parse(Rule::program, source)?; let mut pairs = MistParser::parse(Rule::program, source)?;
println!("{pairs:#?}");
let mut statements = vec![]; let mut statements = vec![];
for pair in pairs.next().unwrap().into_inner() { for pair in pairs.next().unwrap().into_inner() {
@@ -180,19 +182,27 @@ impl From<pest::iterators::Pair<'_, Rule>> for Statement {
Rule::block => Statement::Block(Block::from(pair.into_inner().next().unwrap())), Rule::block => Statement::Block(Block::from(pair.into_inner().next().unwrap())),
Rule::var_decl => { Rule::var_decl_statement => {
let mut inner = pair.into_inner(); let mut inner = pair.into_inner();
let type_ = inner.next().map(TypeExpr::try_from).unwrap().ok(); let mut var_decl = inner.next().unwrap().into_inner();
let name = inner.next().unwrap().as_str().to_string();
let type_ = var_decl.next().map(TypeExpr::try_from).unwrap().ok();
let mutable = if var_decl.peek().unwrap().as_rule() == Rule::mutable {
var_decl.next();
true
} else {
false
};
let name = var_decl.next().unwrap().as_str().to_string();
let init = inner.next().map(Expression::from); let init = inner.next().map(Expression::from);
Statement::VarDecl { Statement::VarDecl(VarDeclStmt {
mutable: false, mutable,
name: name.as_str().to_string(), name: name.as_str().to_string(),
init, init,
type_, type_,
} })
} }
Rule::return_stmt => { Rule::return_stmt => {
@@ -215,11 +225,11 @@ impl From<pest::iterators::Pair<'_, Rule>> for Statement {
let else_branch = inner.next().map(Statement::from); let else_branch = inner.next().map(Statement::from);
Statement::If { Statement::If(IfStmt {
condition, condition,
then_branch: Box::new(then_branch), then_branch: Box::new(then_branch),
else_branch: else_branch.map(Box::new), else_branch: else_branch.map(Box::new),
} })
} }
Rule::while_stmt => { Rule::while_stmt => {
@@ -228,53 +238,10 @@ impl From<pest::iterators::Pair<'_, Rule>> for Statement {
let condition = Expression::from(inner.next().unwrap()); let condition = Expression::from(inner.next().unwrap());
let body = Statement::from(inner.next().unwrap()); let body = Statement::from(inner.next().unwrap());
Statement::While { Statement::While(WhileStmt {
condition, condition,
body: Box::new(body), 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 => {
let mut it = p.into_inner();
let name = it.next().unwrap().as_str().to_string();
let init_expr = it
.next()
.map(|e| Expression::from(e.into_inner().next().unwrap()));
(false, name, init_expr)
}
_ => unimplemented!(
"For loop init parsing not implemented yet: {:?}",
p.as_rule()
),
})
.unwrap();
let condition = inner.next().map(Expression::from);
let update = inner.next().map(parse_var_assign_no_semicolon);
let body = Statement::from(inner.next().unwrap());
Statement::For {
init,
condition,
update: update.map(Box::new),
body: Box::new(body),
}
}
Rule::var_assign => {
let mut inner = pair.into_inner();
let target = Expression::from(inner.next().unwrap());
let value = Expression::from(inner.next().unwrap());
Statement::VarAssign { target, value }
} }
_ => unimplemented!( _ => unimplemented!(
@@ -381,11 +348,3 @@ impl From<pest::iterators::Pair<'_, Rule>> for Postfix {
} }
} }
} }
fn parse_var_assign_no_semicolon(pair: pest::iterators::Pair<Rule>) -> Statement {
let mut inner = pair.into_inner();
let target = Expression::from(inner.next().unwrap());
let value = Expression::from(inner.next().unwrap());
Statement::VarAssign { target, value }
}
+10 -7
View File
@@ -1,4 +1,7 @@
use parser::ast::{BinaryOp, Block, Expression, Postfix, Statement, TopLevel, TypeExpr}; use parser::ast::{
BinaryOp, Block, Expression, IfStmt, Postfix, Statement, TopLevel, TypeExpr, VarAssignStmt,
VarDeclStmt, WhileStmt,
};
pub struct RustCodegen { pub struct RustCodegen {
output: String, output: String,
@@ -128,12 +131,12 @@ impl RustCodegen {
self.add_indentedln("}"); self.add_indentedln("}");
} }
Statement::VarDecl { Statement::VarDecl(VarDeclStmt {
mutable, mutable,
name, name,
init, init,
type_, type_,
} => { }) => {
let mutability = if *mutable { "mut " } else { "" }; let mutability = if *mutable { "mut " } else { "" };
let ty = type_ let ty = type_
@@ -149,7 +152,7 @@ impl RustCodegen {
self.add_indentedln(&format!("let {}{}{}{};", mutability, name, ty, init)); self.add_indentedln(&format!("let {}{}{}{};", mutability, name, ty, init));
} }
Statement::VarAssign { target, value } => { Statement::VarAssign(VarAssignStmt { target, value }) => {
self.add_indentedln(&format!( self.add_indentedln(&format!(
"{} = {};", "{} = {};",
self.generate_expression(target), self.generate_expression(target),
@@ -157,11 +160,11 @@ impl RustCodegen {
)); ));
} }
Statement::If { Statement::If(IfStmt {
condition, condition,
then_branch, then_branch,
else_branch, else_branch,
} => { }) => {
self.add_indentedln(&format!("if {} {{", self.generate_expression(condition))); self.add_indentedln(&format!("if {} {{", self.generate_expression(condition)));
self.indent += 1; self.indent += 1;
@@ -179,7 +182,7 @@ impl RustCodegen {
} }
} }
Statement::While { condition, body } => { Statement::While(WhileStmt { condition, body }) => {
self.add_indentedln(&format!("while {} {{", self.generate_expression(condition))); self.add_indentedln(&format!("while {} {{", self.generate_expression(condition)));
self.indent += 1; self.indent += 1;
+2 -8
View File
@@ -1,9 +1,3 @@
public struct Idk { int test() {
int a, int mut a = 10;
int b,
}
int test(int a, int b) {
Idk bro = Idk { a: 10, b: 10 };
return a + b + bro.a;
} }