cortex_lang/parsing/ast/
statement.rs1use 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}