summaryrefslogtreecommitdiff
path: root/src/ast.rs
diff options
context:
space:
mode:
authorlittleblack111 <littleblack11111@gmail.com>2025-09-27 20:35:59 +0800
committerlittleblack111 <littleblack11111@gmail.com>2025-09-27 20:35:59 +0800
commit477b98d8d271dafdbf4b02137a9068c70637c466 (patch)
tree8b51d1a4c05b3c22a226d3093acc6fbad0bf659b /src/ast.rs
parentb120e413d21a9d4d1961bb814dff88531a7a4855 (diff)
feat: ast
Diffstat (limited to 'src/ast.rs')
-rw-r--r--src/ast.rs53
1 files changed, 48 insertions, 5 deletions
diff --git a/src/ast.rs b/src/ast.rs
index 9777d4e..a87b6a2 100644
--- a/src/ast.rs
+++ b/src/ast.rs
@@ -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