Move code generation into a build script
parent
96ca870db0
commit
8cdfbd61a9
|
@ -1 +1,3 @@
|
||||||
/target
|
/target
|
||||||
|
# Autogenerated
|
||||||
|
/src/ast.rs
|
||||||
|
|
|
@ -4,10 +4,6 @@ version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
default-run = "jlox-rust"
|
default-run = "jlox-rust"
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "astgen"
|
|
||||||
path = "bin/astgen.rs"
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.83"
|
anyhow = "1.0.83"
|
||||||
itertools = "0.12.1"
|
itertools = "0.12.1"
|
||||||
|
|
|
@ -2,26 +2,31 @@
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::BTreeMap,
|
collections::BTreeMap,
|
||||||
|
fs::File,
|
||||||
io::{self, Write},
|
io::{self, Write},
|
||||||
iter,
|
iter,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn main() {
|
pub fn main() {
|
||||||
let mut stdout = io::stdout();
|
let mut ast_file = File::create("./src/ast.rs").expect("could not open src/ast.rs for writing");
|
||||||
|
do_ast_codegen(&mut ast_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_ast_codegen<W: Write>(mut output: W) {
|
||||||
// Autogenerated file, clippy can leave us alone
|
// Autogenerated file, clippy can leave us alone
|
||||||
writeln!(stdout, "#![allow(clippy::all)]").unwrap();
|
writeln!(output, "#![allow(clippy::all)]").unwrap();
|
||||||
|
|
||||||
writeln!(
|
writeln!(
|
||||||
stdout,
|
output,
|
||||||
"// This file is auto-generated. Do not modify it directly, but rather use bin/astgen.rs.\n"
|
"// This file is auto-generated. Do not modify it directly, but rather modify build.rs.\n"
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
define_imports(&mut stdout, &["crate::lex::Token"]).expect("failed to define imports");
|
define_imports(&mut output, &["crate::lex::Token"]).expect("failed to define imports");
|
||||||
writeln!(stdout).unwrap();
|
writeln!(output).unwrap();
|
||||||
|
|
||||||
define_literals(
|
define_literals(
|
||||||
&mut stdout,
|
&mut output,
|
||||||
"LiteralValue",
|
"LiteralValue",
|
||||||
&BTreeMap::from([
|
&BTreeMap::from([
|
||||||
("Number", Some("f64")),
|
("Number", Some("f64")),
|
||||||
|
@ -32,7 +37,7 @@ fn main() {
|
||||||
]),
|
]),
|
||||||
)
|
)
|
||||||
.expect("failed to generate literals");
|
.expect("failed to generate literals");
|
||||||
writeln!(stdout).unwrap();
|
writeln!(output).unwrap();
|
||||||
|
|
||||||
let expr_types = BTreeMap::from([
|
let expr_types = BTreeMap::from([
|
||||||
(
|
(
|
||||||
|
@ -44,21 +49,21 @@ fn main() {
|
||||||
("Literal", "value: LiteralValue"),
|
("Literal", "value: LiteralValue"),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
define_ast(&mut stdout, "Expr", &expr_types).expect("failed to generate ast values");
|
define_ast(&mut output, "Expr", &expr_types).expect("failed to generate ast values");
|
||||||
writeln!(stdout).unwrap();
|
writeln!(output).unwrap();
|
||||||
define_visitor_trait(&mut stdout, "ExprVisitor", "Expr", &expr_types)
|
define_visitor_trait(&mut output, "ExprVisitor", "Expr", &expr_types)
|
||||||
.expect("failed to generate visitor trait");
|
.expect("failed to generate visitor trait");
|
||||||
|
|
||||||
writeln!(stdout).unwrap();
|
writeln!(output).unwrap();
|
||||||
|
|
||||||
let statement_types = BTreeMap::from([
|
let statement_types = BTreeMap::from([
|
||||||
("Expression", "expression: Expr"),
|
("Expression", "expression: Expr"),
|
||||||
("Print", "expression: Expr"),
|
("Print", "expression: Expr"),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
define_ast(&mut stdout, "Stmt", &statement_types).expect("failed to generate ast values");
|
define_ast(&mut output, "Stmt", &statement_types).expect("failed to generate ast values");
|
||||||
writeln!(stdout).unwrap();
|
writeln!(output).unwrap();
|
||||||
define_visitor_trait(&mut stdout, "StmtVisitor", "Stmt", &statement_types)
|
define_visitor_trait(&mut output, "StmtVisitor", "Stmt", &statement_types)
|
||||||
.expect("failed to generate visitor trait");
|
.expect("failed to generate visitor trait");
|
||||||
}
|
}
|
||||||
|
|
70
src/ast.rs
70
src/ast.rs
|
@ -1,70 +0,0 @@
|
||||||
#![allow(clippy::all)]
|
|
||||||
// This file is auto-generated. Do not modify it directly, but rather use bin/astgen.rs.
|
|
||||||
|
|
||||||
use crate::lex::Token;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum LiteralValue {
|
|
||||||
False,
|
|
||||||
Nil,
|
|
||||||
Number(f64),
|
|
||||||
String(String),
|
|
||||||
True,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum Expr {
|
|
||||||
Binary {
|
|
||||||
left: Box<Expr>,
|
|
||||||
operator: Token,
|
|
||||||
right: Box<Expr>,
|
|
||||||
},
|
|
||||||
Grouping {
|
|
||||||
expr: Box<Expr>,
|
|
||||||
},
|
|
||||||
Literal {
|
|
||||||
value: LiteralValue,
|
|
||||||
},
|
|
||||||
Unary {
|
|
||||||
expr: Box<Expr>,
|
|
||||||
operator: Token,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait ExprVisitor<T> {
|
|
||||||
fn visit_expr(&mut self, expr: &Expr) -> T {
|
|
||||||
match expr {
|
|
||||||
Expr::Binary { left, operator, right } => self.visit_binary(left.as_ref(), &operator, right.as_ref()),
|
|
||||||
Expr::Grouping { expr } => self.visit_grouping(expr.as_ref()),
|
|
||||||
Expr::Literal { value } => self.visit_literal(&value),
|
|
||||||
Expr::Unary { expr, operator } => self.visit_unary(expr.as_ref(), &operator),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_binary(&mut self, left: &Expr, operator: &Token, right: &Expr) -> T;
|
|
||||||
fn visit_grouping(&mut self, expr: &Expr) -> T;
|
|
||||||
fn visit_literal(&mut self, value: &LiteralValue) -> T;
|
|
||||||
fn visit_unary(&mut self, expr: &Expr, operator: &Token) -> T;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum Stmt {
|
|
||||||
Expression {
|
|
||||||
expression: Expr,
|
|
||||||
},
|
|
||||||
Print {
|
|
||||||
expression: Expr,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait StmtVisitor<T> {
|
|
||||||
fn visit_stmt(&mut self, stmt: &Stmt) -> T {
|
|
||||||
match stmt {
|
|
||||||
Stmt::Expression { expression } => self.visit_expression(&expression),
|
|
||||||
Stmt::Print { expression } => self.visit_print(&expression),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_expression(&mut self, expression: &Expr) -> T;
|
|
||||||
fn visit_print(&mut self, expression: &Expr) -> T;
|
|
||||||
}
|
|
Loading…
Reference in New Issue