shape_runtime/semantic/
pattern_analysis.rs1use shape_ast::ast::{DestructurePattern, Query, Span, Spanned};
6use shape_ast::error::Result;
7
8use super::types;
9
10impl super::SemanticAnalyzer {
12 pub(super) fn check_pattern_assignment(
14 &mut self,
15 pattern: &DestructurePattern,
16 expr_type: types::Type,
17 ) -> Result<()> {
18 match pattern {
19 DestructurePattern::Identifier(name, _) => {
20 if self.symbol_table.lookup_variable(name).is_some() {
21 self.symbol_table.update_variable(name, expr_type)?;
23 } else {
24 self.symbol_table.define_variable(
26 name,
27 expr_type,
28 shape_ast::ast::VarKind::Var,
29 true,
30 )?;
31 }
32 }
33 DestructurePattern::Array(patterns) => {
34 for pattern in patterns {
36 self.check_pattern_assignment(pattern, expr_type.clone())?;
37 }
38 }
39 DestructurePattern::Object(fields) => {
40 for field in fields {
42 self.check_pattern_assignment(&field.pattern, expr_type.clone())?;
43 }
44 }
45 DestructurePattern::Rest(pattern) => {
46 self.check_pattern_assignment(pattern, expr_type)?;
47 }
48 DestructurePattern::Decomposition(bindings) => {
49 for binding in bindings {
51 if self.symbol_table.lookup_variable(&binding.name).is_some() {
52 self.symbol_table
53 .update_variable(&binding.name, expr_type.clone())?;
54 } else {
55 self.symbol_table.define_variable(
56 &binding.name,
57 expr_type.clone(),
58 shape_ast::ast::VarKind::Var,
59 true,
60 )?;
61 }
62 }
63 }
64 }
65 Ok(())
66 }
67
68 pub(super) fn analyze_query(&mut self, query: &Query, span: Span) -> Result<()> {
70 match query {
71 Query::Backtest(_) => {
72 }
74 Query::Alert(alert) => {
75 let cond_type = self.check_expr_type(&alert.condition)?;
77 if cond_type != types::Type::Bool {
78 return Err(self.error_at(
79 alert.condition.span(),
80 format!("Alert condition must be boolean, got {:?}", cond_type),
81 ));
82 }
83 }
84 Query::With(with_query) => {
85 for cte in &with_query.ctes {
87 self.analyze_query(&cte.query, span)?;
88 }
89 self.analyze_query(&with_query.query, span)?;
91 }
92 }
93
94 Ok(())
95 }
96
97 pub fn list_available_patterns(&self) -> Vec<String> {
99 let mut patterns = self.pattern_library.pattern_names();
100 patterns.sort();
101 patterns.dedup();
102 patterns
103 }
104}