collect top level exprs

This commit is contained in:
minish 2025-09-19 16:02:18 -04:00
parent 2f18cde64a
commit 355d132ba3
Signed by: min
SSH Key Fingerprint: SHA256:mf+pUTmK92Y57BuCjlkBdd82LqztTfDCQIUp0fCKABc
5 changed files with 38 additions and 35 deletions

View File

@ -10,6 +10,7 @@ struct AnalysisScope {
prev: Option<ScopeIdx>, prev: Option<ScopeIdx>,
next: Vec<ScopeIdx>, next: Vec<ScopeIdx>,
idents: Vec<(Ident, u16)>, idents: Vec<(Ident, u16)>,
top_level_exprs: Vec<Expr>,
} }
impl AnalysisScope { impl AnalysisScope {
@ -102,7 +103,9 @@ impl Analyzer {
Expr::Block(a) => { Expr::Block(a) => {
// blocks have their own scope // blocks have their own scope
self.new_scope(); self.new_scope();
let sc = self.get_scope();
// analyze the contents in the new scope // analyze the contents in the new scope
sc.top_level_exprs = a.exprs.clone();
for e in a.exprs { for e in a.exprs {
self.analyze(e); self.analyze(e);
} }

View File

@ -6,7 +6,7 @@ use std::{
use crate::kinds; use crate::kinds;
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq, Clone)]
pub struct Ident(String); pub struct Ident(String);
impl fmt::Display for Ident { impl fmt::Display for Ident {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@ -14,7 +14,7 @@ impl fmt::Display for Ident {
} }
} }
#[derive(Debug)] #[derive(Debug, Clone)]
pub enum Literal { pub enum Literal {
String(String), String(String),
Integer(i64), Integer(i64),

View File

@ -15,7 +15,7 @@ fn main() {
let block = parser.parse().unwrap(); let block = parser.parse().unwrap();
println!("Parse took {:?}", start.elapsed()); println!("Parse took {:?}", start.elapsed());
let e = parser::Expr::Block(block); let e = parser::Expr::Block(block);
// parser::util::display(e); parser::util::display(&e);
let start = Instant::now(); let start = Instant::now();
let mut analysis = compiler::Analyzer::new(); let mut analysis = compiler::Analyzer::new();
analysis.analyze(e); analysis.analyze(e);

View File

@ -7,7 +7,7 @@ use crate::{
pub mod util; pub mod util;
#[derive(Debug)] #[derive(Debug, Clone)]
pub enum Expr { pub enum Expr {
// Data and variables // Data and variables
Assign(Box<Expr>, Box<Expr>), Assign(Box<Expr>, Box<Expr>),
@ -46,7 +46,7 @@ pub enum Expr {
DivideAssign(Box<Expr>, Box<Expr>), DivideAssign(Box<Expr>, Box<Expr>),
} }
#[derive(Debug, Default)] #[derive(Debug, Default, Clone)]
pub struct Block { pub struct Block {
pub exprs: Vec<Expr>, pub exprs: Vec<Expr>,
} }

View File

@ -2,12 +2,12 @@ use std::fmt::Write;
use crate::parser::Expr; use crate::parser::Expr;
pub fn display(e: Expr) { pub fn display(e: &Expr) {
let result = fmt_expr(e, 0); let result = fmt_expr(e, 0);
println!("{result}"); println!("{result}");
} }
fn fmt_binop(left: Expr, right: Expr, op: &str, depth: usize) -> String { fn fmt_binop(left: &Expr, right: &Expr, op: &str, depth: usize) -> String {
format!( format!(
"({} {} {})", "({} {} {})",
fmt_expr(left, depth), fmt_expr(left, depth),
@ -16,16 +16,16 @@ fn fmt_binop(left: Expr, right: Expr, op: &str, depth: usize) -> String {
) )
} }
fn fmt_expr(e: Expr, depth: usize) -> String { fn fmt_expr(e: &Expr, depth: usize) -> String {
match e { match e {
Expr::Assign(l, r) => fmt_binop(*l, *r, "=", depth), Expr::Assign(l, r) => fmt_binop(l, r, "=", depth),
Expr::AddAssign(l, r) => fmt_binop(*l, *r, "+=", depth), Expr::AddAssign(l, r) => fmt_binop(l, r, "+=", depth),
Expr::SubtractAssign(l, r) => fmt_binop(*l, *r, "-=", depth), Expr::SubtractAssign(l, r) => fmt_binop(l, r, "-=", depth),
Expr::MultiplyAssign(l, r) => fmt_binop(*l, *r, "*=", depth), Expr::MultiplyAssign(l, r) => fmt_binop(l, r, "*=", depth),
Expr::DivideAssign(l, r) => fmt_binop(*l, *r, "/=", depth), Expr::DivideAssign(l, r) => fmt_binop(l, r, "/=", depth),
Expr::Literal(l) => l.to_string(), Expr::Literal(l) => l.to_string(),
Expr::Call(l, r) => { Expr::Call(l, r) => {
let mut result = fmt_expr(*l, depth); let mut result = fmt_expr(l, depth);
result.push('('); result.push('(');
let len = r.len(); let len = r.len();
for (i, e) in r.into_iter().enumerate() { for (i, e) in r.into_iter().enumerate() {
@ -38,17 +38,17 @@ fn fmt_expr(e: Expr, depth: usize) -> String {
result result
} }
Expr::If(c, t, f) => { Expr::If(c, t, f) => {
let mut result = format!("if ({}) ({})", fmt_expr(*c, depth), fmt_expr(*t, depth)); let mut result = format!("if ({}) ({})", fmt_expr(c, depth), fmt_expr(t, depth));
if let Some(f) = f { if let Some(f) = f {
let _ = write!(result, " else ({})", fmt_expr(*f, depth)); let _ = write!(result, " else ({})", fmt_expr(f, depth));
} }
result result
} }
Expr::Return(l) => format!("return ({})", fmt_expr(*l, depth)), Expr::Return(l) => format!("return ({})", fmt_expr(l, depth)),
Expr::Block(b) => { Expr::Block(b) => {
let mut result = String::new(); let mut result = String::new();
let len = b.exprs.len(); let len = b.exprs.len();
for (i, expr) in b.exprs.into_iter().enumerate() { for (i, expr) in b.exprs.iter().enumerate() {
result.push_str(&" ".repeat(depth)); result.push_str(&" ".repeat(depth));
result.push_str(&fmt_expr(expr, depth + 1)); result.push_str(&fmt_expr(expr, depth + 1));
if depth != 0 || i + 1 != len { if depth != 0 || i + 1 != len {
@ -66,23 +66,23 @@ fn fmt_expr(e: Expr, depth: usize) -> String {
.map(|e| fmt_expr(e, depth)) .map(|e| fmt_expr(e, depth))
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(", "), .join(", "),
fmt_expr(*e, depth) fmt_expr(e, depth)
), ),
Expr::Negate(l) => format!("(-{})", fmt_expr(*l, depth)), Expr::Negate(l) => format!("(-{})", fmt_expr(l, depth)),
Expr::Not(l) => format!("(!{})", fmt_expr(*l, depth)), Expr::Not(l) => format!("(!{})", fmt_expr(l, depth)),
Expr::EqualTo(l, r) => fmt_binop(*l, *r, "==", depth), Expr::EqualTo(l, r) => fmt_binop(l, r, "==", depth),
Expr::NotEqualTo(l, r) => fmt_binop(*l, *r, "!=", depth), Expr::NotEqualTo(l, r) => fmt_binop(l, r, "!=", depth),
Expr::And(l, r) => fmt_binop(*l, *r, "&&", depth), Expr::And(l, r) => fmt_binop(l, r, "&&", depth),
Expr::Or(l, r) => fmt_binop(*l, *r, "||", depth), Expr::Or(l, r) => fmt_binop(l, r, "||", depth),
Expr::LessThan(l, r) => fmt_binop(*l, *r, "<", depth), Expr::LessThan(l, r) => fmt_binop(l, r, "<", depth),
Expr::LessThanOrEqualTo(l, r) => fmt_binop(*l, *r, "<=", depth), Expr::LessThanOrEqualTo(l, r) => fmt_binop(l, r, "<=", depth),
Expr::GreaterThan(l, r) => fmt_binop(*l, *r, ">", depth), Expr::GreaterThan(l, r) => fmt_binop(l, r, ">", depth),
Expr::GreaterThanOrEqualTo(l, r) => fmt_binop(*l, *r, ">=", depth), Expr::GreaterThanOrEqualTo(l, r) => fmt_binop(l, r, ">=", depth),
Expr::Add(l, r) => fmt_binop(*l, *r, "+", depth), Expr::Add(l, r) => fmt_binop(l, r, "+", depth),
Expr::Subtract(l, r) => fmt_binop(*l, *r, "-", depth), Expr::Subtract(l, r) => fmt_binop(l, r, "-", depth),
Expr::Multiply(l, r) => fmt_binop(*l, *r, "*", depth), Expr::Multiply(l, r) => fmt_binop(l, r, "*", depth),
Expr::Divide(l, r) => fmt_binop(*l, *r, "/", depth), Expr::Divide(l, r) => fmt_binop(l, r, "/", depth),
Expr::Exponent(l, r) => fmt_binop(*l, *r, "**", depth), Expr::Exponent(l, r) => fmt_binop(l, r, "**", depth),
Expr::Modulo(l, r) => fmt_binop(*l, *r, "%", depth), Expr::Modulo(l, r) => fmt_binop(l, r, "%", depth),
} }
} }