amarok_syntax/
lib.rs

1//! Core syntax structures for the Amarok language.
2//!
3//! This crate defines the Abstract Syntax Tree (AST).
4//! It contains NO parsing and NO execution logic.
5
6use std::fmt;
7mod diagnostic;
8mod source_map;
9mod span;
10pub use diagnostic::Diagnostic;
11pub use source_map::{FileId, SourceFile, SourceMap};
12pub use span::{Span, Spanned};
13
14#[derive(Debug, Clone, PartialEq)]
15pub struct Program {
16    pub statements: Vec<Spanned<Statement>>,
17}
18
19#[derive(Debug, Clone, PartialEq)]
20pub enum Statement {
21    Assignment {
22        name: String,
23        value: Spanned<Expression>,
24    },
25    Expression {
26        expression: Spanned<Expression>,
27    },
28    Block {
29        statements: Vec<Spanned<Statement>>,
30    },
31    If {
32        condition: Spanned<Expression>,
33        then_branch: Vec<Spanned<Statement>>,
34        else_branch: Vec<Spanned<Statement>>,
35    },
36    While {
37        condition: Spanned<Expression>,
38        body: Vec<Spanned<Statement>>,
39    },
40    FunctionDefinition {
41        name: String,
42        parameters: Vec<String>,
43        body: Vec<Spanned<Statement>>,
44    },
45    Return {
46        value: Option<Spanned<Expression>>,
47    },
48    /// `use a::b::c;` — load module file `a/b/c.amarok` and flat-merge its
49    /// top-level functions and variables into the current scope.
50    Use {
51        path: Vec<String>,
52    },
53}
54
55#[derive(Debug, Clone, PartialEq)]
56pub enum Expression {
57    Integer(i64),
58    String(String),
59    Variable(String),
60    Binary {
61        left: Box<Spanned<Expression>>,
62        operator: BinaryOperator,
63        right: Box<Spanned<Expression>>,
64    },
65    FunctionCall {
66        path: Vec<String>,
67        arguments: Vec<Spanned<Expression>>,
68    },
69}
70/// Supported binary operators.
71#[derive(Debug, Clone, Copy, PartialEq, Eq)]
72pub enum BinaryOperator {
73    Add,
74    Subtract,
75    Multiply,
76    Divide,
77}
78
79impl fmt::Display for BinaryOperator {
80    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
81        let symbol = match self {
82            BinaryOperator::Add => "+",
83            BinaryOperator::Subtract => "-",
84            BinaryOperator::Multiply => "*",
85            BinaryOperator::Divide => "/",
86        };
87        write!(formatter, "{symbol}")
88    }
89}