Merge pull request #16 from mist-go/updated-grammar-ast
Updated grammar and AST
This commit is contained in:
+40
-38
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user