bril_frontend/
ast.rs

1// Copyright (C) 2024 Ethan Uppal.
2//
3// This Source Code Form is subject to the terms of the Mozilla Public License,
4// v. 2.0. If a copy of the MPL was not distributed with this file, You can
5// obtain one at https://mozilla.org/MPL/2.0/.
6
7use std::fmt;
8
9use crate::loc::Loc;
10
11pub struct Program<'a> {
12    pub items: Vec<TopLevelItem<'a>>,
13}
14
15impl<'a> Program<'a> {
16    pub fn imports(&self) -> impl Iterator<Item = &Loc<Import<'a>>> {
17        self.items.iter().filter_map(|item| match item {
18            TopLevelItem::Import(import) => Some(import),
19            _ => None,
20        })
21    }
22
23    pub fn functions(&self) -> impl Iterator<Item = &Loc<Function<'a>>> {
24        self.items.iter().filter_map(|item| match item {
25            TopLevelItem::Function(function) => Some(function),
26            _ => None,
27        })
28    }
29}
30
31pub enum TopLevelItem<'a> {
32    Import(Loc<Import<'a>>),
33    Function(Loc<Function<'a>>),
34    Comment(Loc<&'a str>),
35    Newline(Loc<()>),
36}
37
38pub struct ImportedFunctionAlias<'a> {
39    pub as_token: Loc<()>,
40    pub name: Loc<&'a str>,
41}
42
43pub struct ImportedFunction<'a> {
44    pub name: Loc<&'a str>,
45    pub alias: Option<Loc<ImportedFunctionAlias<'a>>>,
46}
47
48pub struct Import<'a> {
49    pub from_token: Loc<()>,
50    pub path: Loc<&'a str>,
51    pub import_token: Loc<()>,
52    pub imported_functions: Vec<Loc<ImportedFunction<'a>>>,
53}
54
55pub struct Function<'a> {
56    pub name: Loc<&'a str>,
57    pub parameters: Vec<(Loc<&'a str>, Loc<TypeAnnotation>)>,
58    pub return_type: Option<Loc<TypeAnnotation>>,
59    pub body: Vec<Loc<FunctionCode<'a>>>,
60}
61
62pub enum FunctionCode<'a> {
63    Label {
64        label: Loc<Label<'a>>,
65        colon_token: Loc<()>,
66        comment: Option<Loc<&'a str>>,
67    },
68    Instruction {
69        inner: Loc<Instruction<'a>>,
70        comment: Option<Loc<&'a str>>,
71    },
72    Comment(Loc<&'a str>),
73    EmptyLine(Loc<()>),
74}
75
76pub struct Label<'a> {
77    pub name: Loc<&'a str>,
78}
79
80#[derive(Debug, Clone)]
81pub enum Type {
82    Int,
83    Bool,
84    Float,
85    Char,
86    Ptr(Box<Loc<Type>>),
87}
88
89impl Type {
90    pub fn is_same_type_as(&self, other: &Self) -> bool {
91        match (self, other) {
92            (Type::Int, Type::Int)
93            | (Type::Bool, Type::Bool)
94            | (Type::Float, Type::Float)
95            | (Type::Char, Type::Char) => true,
96            (Type::Ptr(inner), Type::Ptr(inner2)) => inner.is_same_type_as(inner2),
97            _ => false,
98        }
99    }
100}
101
102impl fmt::Display for Type {
103    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104        match self {
105            Type::Int => "int".fmt(f),
106            Type::Bool => "bool".fmt(f),
107            Type::Float => "float".fmt(f),
108            Type::Char => "char".fmt(f),
109            Type::Ptr(inner) => write!(f, "ptr<{}>", inner),
110        }
111    }
112}
113
114pub struct TypeAnnotation {
115    pub colon_token: Loc<()>,
116    pub ty: Loc<Type>,
117}
118
119pub enum Instruction<'a> {
120    Constant(Loc<Constant<'a>>),
121    ValueOperation(Loc<ValueOperation<'a>>),
122    EffectOperation(Loc<EffectOperation<'a>>),
123}
124
125pub enum ConstantValue {
126    IntegerLiteral(Loc<i64>),
127    BooleanLiteral(Loc<bool>),
128    FloatLiteral(Loc<f64>),
129    CharacterLiteral(Loc<char>),
130}
131
132pub struct Constant<'a> {
133    pub name: Loc<&'a str>,
134    pub type_annotation: Option<Loc<TypeAnnotation>>,
135    pub equals_token: Loc<()>,
136    pub const_token: Loc<()>,
137    pub value: Loc<ConstantValue>,
138    pub semi_token: Loc<()>,
139}
140
141pub enum ValueOperationOp<'a> {
142    Add(Loc<&'a str>, Loc<&'a str>),
143    Mul(Loc<&'a str>, Loc<&'a str>),
144    Sub(Loc<&'a str>, Loc<&'a str>),
145    Div(Loc<&'a str>, Loc<&'a str>),
146
147    Eq(Loc<&'a str>, Loc<&'a str>),
148    Lt(Loc<&'a str>, Loc<&'a str>),
149    Gt(Loc<&'a str>, Loc<&'a str>),
150    Le(Loc<&'a str>, Loc<&'a str>),
151    Ge(Loc<&'a str>, Loc<&'a str>),
152
153    Not(Loc<&'a str>),
154    And(Loc<&'a str>, Loc<&'a str>),
155    Or(Loc<&'a str>, Loc<&'a str>),
156
157    /// Value-operation version.
158    Call(Loc<&'a str>, Vec<Loc<&'a str>>),
159    Id(Loc<&'a str>),
160
161    Fadd(Loc<&'a str>, Loc<&'a str>),
162    Fmul(Loc<&'a str>, Loc<&'a str>),
163    Fsub(Loc<&'a str>, Loc<&'a str>),
164    Fdiv(Loc<&'a str>, Loc<&'a str>),
165    Feq(Loc<&'a str>, Loc<&'a str>),
166    Flt(Loc<&'a str>, Loc<&'a str>),
167    Fle(Loc<&'a str>, Loc<&'a str>),
168    Fgt(Loc<&'a str>, Loc<&'a str>),
169    Fge(Loc<&'a str>, Loc<&'a str>),
170
171    Alloc(Loc<&'a str>),
172    Load(Loc<&'a str>),
173    PtrAdd(Loc<&'a str>, Loc<&'a str>),
174
175    Ceq(Loc<&'a str>, Loc<&'a str>),
176    Clt(Loc<&'a str>, Loc<&'a str>),
177    Cgt(Loc<&'a str>, Loc<&'a str>),
178    Cle(Loc<&'a str>, Loc<&'a str>),
179    Cge(Loc<&'a str>, Loc<&'a str>),
180    Char2Int(Loc<&'a str>),
181    Int2Char(Loc<&'a str>),
182}
183
184pub struct ValueOperation<'a> {
185    pub name: Loc<&'a str>,
186    pub type_annotation: Option<Loc<TypeAnnotation>>,
187    pub equals_token: Loc<()>,
188    pub op: Loc<ValueOperationOp<'a>>,
189    pub semi_token: Loc<()>,
190}
191
192pub enum EffectOperationOp<'a> {
193    Jmp(Loc<Label<'a>>),
194    Br(Loc<&'a str>, Loc<Label<'a>>, Loc<Label<'a>>),
195    /// Effect-operation version.
196    Call(Loc<&'a str>, Vec<Loc<&'a str>>),
197    Ret(Option<Loc<&'a str>>),
198
199    Print(Vec<Loc<&'a str>>),
200    Nop,
201
202    Store(Loc<&'a str>, Loc<&'a str>),
203    Free(Loc<&'a str>),
204}
205
206pub struct EffectOperation<'a> {
207    pub op: Loc<EffectOperationOp<'a>>,
208    pub semi_token: Loc<()>,
209}