cortex_lang/parsing/ast/
statement.rs

1use crate::parsing::codegen::r#trait::SimpleCodeGen;
2
3use super::{expression::{PConditionBody, PExpression, IdentExpression, OptionalIdentifier}, r#type::CortexType};
4
5#[derive(Clone)]
6pub enum AssignmentName {
7    Single(IdentExpression),
8    Tuple(Vec<AssignmentName>),
9    Ignore,
10}
11impl SimpleCodeGen for AssignmentName {
12    fn codegen(&self, indent: usize) -> String {
13        match self {
14            AssignmentName::Single(ident_expression) => {
15                ident_expression.codegen(indent)
16            },
17            AssignmentName::Tuple(items) => {
18                if items.len() == 1 {
19                    format!("({},)", items.get(0).unwrap().codegen(indent))
20                } else {
21                    format!("({})", items.iter().map(|i| i.codegen(indent)).collect::<Vec<_>>().join(", "))
22                }
23            },
24            AssignmentName::Ignore => String::from("~"),
25        }
26    }
27}
28
29#[derive(Clone)]
30pub enum DeclarationName {
31    Single(OptionalIdentifier),
32    Tuple(Vec<DeclarationName>),
33}
34impl SimpleCodeGen for DeclarationName {
35    fn codegen(&self, indent: usize) -> String {
36        match self {
37            DeclarationName::Single(elem) => {
38                elem.codegen(indent)
39            },
40            DeclarationName::Tuple(items) => {
41                if items.len() == 1 {
42                    format!("({},)", items.get(0).unwrap().codegen(indent))
43                } else {
44                    format!("({})", items.iter().map(|i| i.codegen(indent)).collect::<Vec<_>>().join(", "))
45                }
46            },
47        }
48    }
49}
50
51#[derive(Clone)]
52pub enum PStatement {
53    Expression(PExpression),
54    Throw(PExpression),
55    VariableDeclaration {
56        name: DeclarationName,
57        is_const: bool,
58        typ: Option<CortexType>,
59        initial_value: PExpression,
60    },
61    Assignment {
62        name: AssignmentName,
63        value: PExpression,
64    },
65    WhileLoop(PConditionBody),
66    Break,
67    Continue,
68}
69impl SimpleCodeGen for PStatement {
70    fn codegen(&self, indent: usize) -> String {
71        let mut s = String::new();
72        let indent_prefix = "    ".repeat(indent);
73        s.push_str(&indent_prefix);
74        let mut semicolon = true;
75        match self {
76            Self::Expression(expr) => {
77                s.push_str(&expr.codegen(indent));
78            },
79            Self::Throw(expr) => {
80                s.push_str("throw ");
81                s.push_str(&expr.codegen(indent));
82            },
83            Self::VariableDeclaration { name, is_const, typ, initial_value } => {
84                if *is_const {
85                    s.push_str("const ");
86                } else {
87                    s.push_str("let ");
88                }
89                s.push_str(&name.codegen(indent));
90                if let Some(given_type) = typ {
91                    s.push_str(": ");
92                    s.push_str(&given_type.codegen(indent));
93                }
94                s.push_str(" = ");
95                s.push_str(&initial_value.codegen(indent));
96            },
97            Self::Assignment { name, value } => {
98                s.push_str(&name.codegen(indent));
99                s.push_str(" = ");
100                s.push_str(&value.codegen(indent));
101            },
102            Self::WhileLoop(cond_body) => {
103                semicolon = false;
104                s.push_str("while ");
105                s.push_str(&cond_body.condition.codegen(indent));
106                s.push_str(" {\n");
107                s.push_str(&cond_body.body.codegen(indent + 1));
108                s.push_str(&indent_prefix);
109                s.push_str("}");
110            },
111            Self::Break => {
112                s.push_str("break");
113            },
114            Self::Continue => {
115                s.push_str("continue");
116            },
117        }
118        if semicolon {
119            s.push_str(";");
120        }
121        s
122    }
123}