xbasic/
stmt.rs

1use crate::expr::Expr;
2use crate::tokens::{Token, TokenType};
3use crate::visitor::StmtVisitor;
4
5#[derive(Clone)]
6pub(crate) struct Stmt {
7	content: StmtContent,
8	pub(crate) line: usize,
9}
10
11#[derive(Clone)]
12enum StmtContent {
13	Expression(ExpressionStmt),
14	Print(PrintStmt),
15	Input(InputStmt),
16	Assign(AssignStmt),
17	If(IfStmt),
18	While(WhileStmt),
19	For(ForStmt),
20	Return(ReturnStmt),
21	BinaryAssign(BinaryAssignStmt),
22}
23
24impl Stmt {
25	pub fn new_print(values: Vec<Expr>, line: usize) -> Self {
26		Self {
27			line,
28			content: StmtContent::Print(PrintStmt { values }),
29		}
30	}
31
32	pub fn new_input(variable: Token) -> Self {
33		Self {
34			line: variable.line,
35			content: StmtContent::Input(InputStmt { variable }),
36		}
37	}
38
39	pub fn new_expression(value: Expr, line: usize) -> Self {
40		Self {
41			line,
42			content: StmtContent::Expression(ExpressionStmt { value }),
43		}
44	}
45
46	pub fn new_assign(name: Token, value: Expr, line: usize) -> Self {
47		Self {
48			line,
49			content: StmtContent::Assign(AssignStmt { name, value }),
50		}
51	}
52
53	pub fn new_if(
54		condition: Expr,
55		then_stmts: Vec<Stmt>,
56		else_stmts: Vec<Stmt>,
57		line: usize,
58	) -> Self {
59		Self {
60			line,
61			content: StmtContent::If(IfStmt {
62				condition,
63				then_stmts,
64				else_stmts,
65			}),
66		}
67	}
68
69	pub fn new_for(
70		variable: Token,
71		min_value: Expr,
72		max_value: Expr,
73		body: Vec<Stmt>,
74		line: usize,
75	) -> Self {
76		Self {
77			line,
78			content: StmtContent::For(ForStmt {
79				variable,
80				min_value,
81				max_value,
82				body,
83			}),
84		}
85	}
86
87	pub fn new_while(condition: Expr, body: Vec<Stmt>, line: usize) -> Self {
88		Self {
89			line,
90			content: StmtContent::While(WhileStmt { condition, body }),
91		}
92	}
93
94	pub fn new_return(return_value: Expr, line: usize) -> Self {
95		Self {
96			line,
97			content: StmtContent::Return(ReturnStmt { return_value }),
98		}
99	}
100
101	pub fn new_binary_assign(name: Token, operator: TokenType, value: Expr, line: usize) -> Self {
102		Self {
103			line,
104			content: StmtContent::BinaryAssign(BinaryAssignStmt {
105				name,
106				operator,
107				value,
108			}),
109		}
110	}
111
112	pub(crate) fn accept<U, V>(&self, visitor: &mut V) -> U
113	where
114		V: StmtVisitor<U>,
115	{
116		let line = self.line;
117		match &self.content {
118			StmtContent::Assign(stmt) => visitor.visit_assign_stmt(stmt, line),
119			StmtContent::Expression(stmt) => visitor.visit_expression_stmt(stmt, line),
120			StmtContent::Print(stmt) => visitor.visit_print_stmt(stmt, line),
121			StmtContent::Input(stmt) => visitor.visit_input_stmt(stmt, line),
122			StmtContent::If(stmt) => visitor.visit_if_stmt(stmt, line),
123			StmtContent::While(stmt) => visitor.visit_while_stmt(stmt, line),
124			StmtContent::For(stmt) => visitor.visit_for_stmt(stmt, line),
125			StmtContent::Return(stmt) => visitor.visit_return_stmt(stmt, line),
126			StmtContent::BinaryAssign(stmt) => visitor.visit_binary_assign_stmt(stmt, line),
127		}
128	}
129}
130
131#[derive(Clone)]
132pub(crate) struct PrintStmt {
133	pub values: Vec<Expr>,
134}
135
136#[derive(Clone)]
137pub(crate) struct InputStmt {
138	pub variable: Token,
139}
140
141#[derive(Clone)]
142pub(crate) struct ExpressionStmt {
143	pub value: Expr,
144}
145
146#[derive(Clone)]
147pub(crate) struct AssignStmt {
148	pub name: Token,
149	pub value: Expr,
150}
151
152#[derive(Clone)]
153pub(crate) struct IfStmt {
154	pub condition: Expr,
155	pub then_stmts: Vec<Stmt>,
156	pub else_stmts: Vec<Stmt>,
157}
158
159#[derive(Clone)]
160pub(crate) struct WhileStmt {
161	pub condition: Expr,
162	pub body: Vec<Stmt>,
163}
164
165#[derive(Clone)]
166pub(crate) struct ForStmt {
167	pub variable: Token,
168	pub min_value: Expr,
169	pub max_value: Expr,
170	pub body: Vec<Stmt>,
171}
172
173#[derive(Clone)]
174pub(crate) struct ReturnStmt {
175	pub return_value: Expr,
176}
177
178#[derive(Clone)]
179pub(crate) struct BinaryAssignStmt {
180	pub name: Token,
181	pub operator: TokenType,
182	pub value: Expr,
183}