diff options
| author | littleblack111 <littleblack11111@gmail.com> | 2025-09-27 20:35:59 +0800 |
|---|---|---|
| committer | littleblack111 <littleblack11111@gmail.com> | 2025-09-27 20:35:59 +0800 |
| commit | 477b98d8d271dafdbf4b02137a9068c70637c466 (patch) | |
| tree | 8b51d1a4c05b3c22a226d3093acc6fbad0bf659b /src/ast.rs | |
| parent | b120e413d21a9d4d1961bb814dff88531a7a4855 (diff) | |
feat: ast
Diffstat (limited to 'src/ast.rs')
| -rw-r--r-- | src/ast.rs | 53 |
1 files changed, 48 insertions, 5 deletions
@@ -1,17 +1,18 @@ -use crate::parser::{self, Expr, ExprT, Scope}; +use crate::parser::{Expr, ExprT, Metadata, Scope}; +#[derive(Clone, Debug)] pub enum DepthExpr<'a> { Decision { cond: Box<DepthExpr<'a>>, t: Scope, - else_branch: Option<Box<DepthExpr<'a>>>, + else_branch: Option<Box<Vec<DepthExpr<'a>>>>, }, IO(&'a str), Process(&'a str), } -fn parse(vec: Vec<Expr>) -> Vec<DepthExpr> { - let exprs = Vec::new(); +pub fn parse<'a, 'b>(vec: &'b Vec<Expr<'a>>) -> Vec<DepthExpr<'a>> { + let mut exprs: Vec<DepthExpr<'a>> = Vec::new(); let mut it = vec .iter() @@ -19,8 +20,50 @@ fn parse(vec: Vec<Expr>) -> Vec<DepthExpr> { while let Some(e) = it.next() { if let ExprT::Decision((cond, scope)) = e.expr { - let cond = parser::parse(cond); + let cond = DepthExpr::Process(cond); + for e in it.clone() { + if e.meta == Some(Metadata::EndScope) { + break; + } + } + + exprs.push(DepthExpr::Decision { + cond: Box::new(cond), + t: scope, + else_branch: Some(Box::new(parse(&entire_scopes( + it.clone() + .cloned(), + )))), + }); + } + } + + exprs +} + +fn entire_scopes<'a>(it: impl Iterator<Item = Expr<'a>>) -> Vec<Expr<'a>> { + let mut exprs: Vec<Expr<'a>> = Vec::new(); + let mut scope_count: u32 = 1; // assume we already entered the scope + + for i in it { + if scope_count == 0 { + break; + } + if let Some(meta) = i.meta { + match meta { + Metadata::StartScope => { + scope_count = scope_count + .checked_add(1) + .expect("Scopes nested too deep") + } + Metadata::EndScope => { + scope_count = scope_count + .checked_sub(1) + .expect("Closed not opened scope") + } + } } + exprs.push(i); } exprs |
