1use crate::Location;
2use crate::Visitor;
3use slang_types::types::TypeId;
4use std::fmt::Display;
5
6#[derive(Debug, PartialEq)]
7pub enum BinaryOperator {
8 Add,
10 Subtract,
12 Multiply,
14 Divide,
16 GreaterThan,
18 LessThan,
20 GreaterThanOrEqual,
22 LessThanOrEqual,
24 Equal,
26 NotEqual,
28 And,
30 Or,
32}
33
34impl Display for BinaryOperator {
35 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36 let op_str = match self {
37 BinaryOperator::Add => "+",
38 BinaryOperator::Subtract => "-",
39 BinaryOperator::Multiply => "*",
40 BinaryOperator::Divide => "/",
41 BinaryOperator::GreaterThan => ">",
42 BinaryOperator::LessThan => "<",
43 BinaryOperator::GreaterThanOrEqual => ">=",
44 BinaryOperator::LessThanOrEqual => "<=",
45 BinaryOperator::Equal => "==",
46 BinaryOperator::NotEqual => "!=",
47 BinaryOperator::And => "&&",
48 BinaryOperator::Or => "||",
49 };
50 write!(f, "{}", op_str)
51 }
52}
53
54#[derive(Debug, PartialEq)]
55pub enum UnaryOperator {
56 Negate,
58 Not,
60}
61
62impl Display for UnaryOperator {
63 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64 let op_str = match self {
65 UnaryOperator::Negate => "-",
66 UnaryOperator::Not => "!",
67 };
68 write!(f, "{}", op_str)
69 }
70}
71
72#[derive(Debug)]
74pub enum Expression {
75 Literal(LiteralExpr),
77 Binary(BinaryExpr),
79 Variable(VariableExpr),
81 Unary(UnaryExpr),
83 Call(FunctionCallExpr),
85 Conditional(ConditionalExpr),
87 Block(BlockExpr),
89 FunctionType(FunctionTypeExpr),
91}
92
93impl Expression {
94 pub fn location(&self) -> Location {
95 match self {
96 Expression::Literal(e) => e.location,
97 Expression::Binary(e) => e.location,
98 Expression::Variable(e) => e.location,
99 Expression::Unary(e) => e.location,
100 Expression::Call(e) => e.location,
101 Expression::Conditional(e) => e.location,
102 Expression::Block(e) => e.location,
103 Expression::FunctionType(e) => e.location,
104 }
105 }
106}
107
108#[derive(Debug)]
110pub enum Statement {
111 Let(LetStatement),
113 Assignment(AssignmentStatement),
115 Expression(Expression),
117 TypeDefinition(TypeDefinitionStmt),
119 FunctionDeclaration(FunctionDeclarationStmt),
121 Return(ReturnStatement),
123 If(IfStatement),
125}
126
127#[derive(Debug)]
129pub struct FunctionCallExpr {
130 pub name: String,
132 pub arguments: Vec<Expression>,
134 pub expr_type: TypeId,
136 pub location: Location,
138}
139
140#[derive(Debug)]
142pub struct ConditionalExpr {
143 pub condition: Box<Expression>,
145 pub then_branch: Box<Expression>,
147 pub else_branch: Box<Expression>,
149 pub expr_type: TypeId,
151 pub location: Location,
153}
154
155#[derive(Debug)]
157pub struct BlockExpr {
158 pub statements: Vec<Statement>,
160 pub return_expr: Option<Box<Expression>>,
162 pub expr_type: TypeId,
164 pub location: Location,
166}
167
168#[derive(Debug)]
170pub struct Parameter {
171 pub name: String,
173 pub param_type: TypeId,
175 pub location: Location,
177}
178
179#[derive(Debug)]
181pub struct FunctionDeclarationStmt {
182 pub name: String,
184 pub parameters: Vec<Parameter>,
186 pub return_type: TypeId,
188 pub body: BlockExpr,
190 pub location: Location,
192}
193
194#[derive(Debug)]
196pub struct FunctionTypeExpr {
197 pub param_types: Vec<TypeId>,
199 pub return_type: TypeId,
201 pub expr_type: TypeId,
203 pub location: Location,
205}
206
207#[derive(Debug)]
209pub struct TypeDefinitionStmt {
210 pub name: String,
212 pub fields: Vec<(String, TypeId)>,
214 pub location: Location,
216}
217
218#[derive(Debug)]
220pub struct LiteralExpr {
221 pub value: LiteralValue,
223 pub expr_type: TypeId,
225 pub location: Location,
227}
228
229#[derive(Debug)]
231pub struct VariableExpr {
232 pub name: String,
234 pub location: Location,
236}
237
238#[derive(Debug)]
240pub struct UnaryExpr {
241 pub operator: UnaryOperator,
243 pub right: Box<Expression>,
245 pub expr_type: TypeId,
247 pub location: Location,
249}
250
251#[derive(Debug)]
253pub enum LiteralValue {
254 I32(i32),
256 I64(i64),
258 U32(u32),
260 U64(u64),
262 UnspecifiedInteger(i64),
264 F32(f32),
266 F64(f64),
268 UnspecifiedFloat(f64),
270 String(String),
272 Boolean(bool),
274 Unit,
276}
277
278#[derive(Debug)]
280pub struct BinaryExpr {
281 pub left: Box<Expression>,
283 pub operator: BinaryOperator,
285 pub right: Box<Expression>,
287 pub expr_type: TypeId,
289 pub location: Location,
291}
292
293#[derive(Debug)]
295pub struct LetStatement {
296 pub name: String,
298 pub is_mutable: bool,
300 pub value: Expression,
302 pub expr_type: TypeId,
304 pub location: Location,
306}
307
308#[derive(Debug)]
310pub struct AssignmentStatement {
311 pub name: String,
313 pub value: Expression,
315 pub location: Location,
317}
318
319#[derive(Debug)]
321pub struct IfStatement {
322 pub condition: Expression,
324 pub then_branch: BlockExpr,
326 pub else_branch: Option<BlockExpr>,
328 pub location: Location,
330}
331
332#[derive(Debug)]
334pub struct ReturnStatement {
335 pub value: Option<Expression>,
337 pub location: Location,
339}
340
341impl Statement {
342 pub fn accept<T>(&self, visitor: &mut dyn Visitor<T>) -> T {
350 match self {
351 Statement::Let(let_stmt) => visitor.visit_let_statement(let_stmt),
352 Statement::Assignment(assign_stmt) => visitor.visit_assignment_statement(assign_stmt),
353 Statement::Expression(expr) => visitor.visit_expression_statement(expr),
354 Statement::TypeDefinition(type_def) => {
355 visitor.visit_type_definition_statement(type_def)
356 }
357 Statement::FunctionDeclaration(fn_decl) => {
358 visitor.visit_function_declaration_statement(fn_decl)
359 }
360 Statement::Return(return_stmt) => visitor.visit_return_statement(return_stmt),
361 Statement::If(if_stmt) => visitor.visit_if_statement(if_stmt),
362 }
363 }
364}
365
366impl Expression {
367 pub fn accept<T>(&self, visitor: &mut dyn Visitor<T>) -> T {
375 match self {
376 Expression::Literal(lit) => visitor.visit_literal_expression(lit),
377 Expression::Binary(bin) => visitor.visit_binary_expression(bin),
378 Expression::Variable(var) => visitor.visit_variable_expression(var),
379 Expression::Unary(unary) => visitor.visit_unary_expression(unary),
380 Expression::Call(call) => visitor.visit_call_expression(call),
381 Expression::Conditional(cond) => visitor.visit_conditional_expression(cond),
382 Expression::Block(block) => visitor.visit_block_expression(block),
383 Expression::FunctionType(func_type) => {
384 visitor.visit_function_type_expression(func_type)
385 }
386 }
387 }
388}