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 imports: Vec<Loc<Import<'a>>>,
13    pub functions: Vec<Loc<Function<'a>>>,
14}
15
16pub struct ImportedFunctionAlias<'a> {
17    pub as_token: Loc<()>,
18    pub name: Loc<&'a str>,
19}
20
21pub struct ImportedFunction<'a> {
22    pub name: Loc<&'a str>,
23    pub alias: Option<Loc<ImportedFunctionAlias<'a>>>,
24}
25
26pub struct Import<'a> {
27    pub from_token: Loc<()>,
28    pub path: Loc<&'a str>,
29    pub import_token: Loc<()>,
30    pub imported_functions: Vec<Loc<ImportedFunction<'a>>>,
31}
32
33pub struct Function<'a> {
34    pub name: Loc<&'a str>,
35    pub parameters: Vec<(Loc<&'a str>, Loc<TypeAnnotation>)>,
36    pub return_type: Option<Loc<TypeAnnotation>>,
37    pub body: Vec<Loc<FunctionCode<'a>>>,
38}
39
40pub enum FunctionCode<'a> {
41    Label {
42        label: Loc<Label<'a>>,
43        colon_token: Loc<()>,
44    },
45    Instruction(Loc<Instruction<'a>>),
46}
47
48pub struct Label<'a> {
49    pub name: Loc<&'a str>,
50}
51
52#[derive(Debug, Clone)]
53pub enum Type {
54    Int,
55    Bool,
56    Float,
57    Char,
58    Ptr(Box<Loc<Type>>),
59}
60
61impl Type {
62    pub fn is_same_type_as(&self, other: &Self) -> bool {
63        match (self, other) {
64            (Type::Int, Type::Int)
65            | (Type::Bool, Type::Bool)
66            | (Type::Float, Type::Float)
67            | (Type::Char, Type::Char) => true,
68            (Type::Ptr(inner), Type::Ptr(inner2)) => inner.is_same_type_as(inner2),
69            _ => false,
70        }
71    }
72}
73
74impl fmt::Display for Type {
75    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76        match self {
77            Type::Int => "int".fmt(f),
78            Type::Bool => "bool".fmt(f),
79            Type::Float => "float".fmt(f),
80            Type::Char => "char".fmt(f),
81            Type::Ptr(inner) => write!(f, "ptr<{}>", inner),
82        }
83    }
84}
85
86pub struct TypeAnnotation {
87    pub colon_token: Loc<()>,
88    pub ty: Loc<Type>,
89}
90
91pub enum Instruction<'a> {
92    Constant(Loc<Constant<'a>>),
93    ValueOperation(Loc<ValueOperation<'a>>),
94    EffectOperation(Loc<EffectOperation<'a>>),
95}
96
97pub enum ConstantValue {
98    IntegerLiteral(Loc<i64>),
99    BooleanLiteral(Loc<bool>),
100    FloatLiteral(Loc<f64>),
101    CharacterLiteral(Loc<char>),
102}
103
104pub struct Constant<'a> {
105    pub name: Loc<&'a str>,
106    pub type_annotation: Option<Loc<TypeAnnotation>>,
107    pub equals_token: Loc<()>,
108    pub const_token: Loc<()>,
109    pub value: Loc<ConstantValue>,
110    pub semi_token: Loc<()>,
111}
112
113pub enum ValueOperationOp<'a> {
114    Add(Loc<&'a str>, Loc<&'a str>),
115    Mul(Loc<&'a str>, Loc<&'a str>),
116    Sub(Loc<&'a str>, Loc<&'a str>),
117    Div(Loc<&'a str>, Loc<&'a str>),
118
119    Eq(Loc<&'a str>, Loc<&'a str>),
120    Lt(Loc<&'a str>, Loc<&'a str>),
121    Gt(Loc<&'a str>, Loc<&'a str>),
122    Le(Loc<&'a str>, Loc<&'a str>),
123    Ge(Loc<&'a str>, Loc<&'a str>),
124
125    Not(Loc<&'a str>),
126    And(Loc<&'a str>, Loc<&'a str>),
127    Or(Loc<&'a str>, Loc<&'a str>),
128
129    /// Value-operation version.
130    Call(Loc<&'a str>, Vec<Loc<&'a str>>),
131    Id(Loc<&'a str>),
132
133    Fadd(Loc<&'a str>, Loc<&'a str>),
134    Fmul(Loc<&'a str>, Loc<&'a str>),
135    Fsub(Loc<&'a str>, Loc<&'a str>),
136    Fdiv(Loc<&'a str>, Loc<&'a str>),
137    Feq(Loc<&'a str>, Loc<&'a str>),
138    Flt(Loc<&'a str>, Loc<&'a str>),
139    Fle(Loc<&'a str>, Loc<&'a str>),
140    Fgt(Loc<&'a str>, Loc<&'a str>),
141    Fge(Loc<&'a str>, Loc<&'a str>),
142
143    Alloc(Loc<&'a str>),
144    Load(Loc<&'a str>),
145    PtrAdd(Loc<&'a str>, Loc<&'a str>),
146
147    Ceq(Loc<&'a str>, Loc<&'a str>),
148    Clt(Loc<&'a str>, Loc<&'a str>),
149    Cgt(Loc<&'a str>, Loc<&'a str>),
150    Cle(Loc<&'a str>, Loc<&'a str>),
151    Cge(Loc<&'a str>, Loc<&'a str>),
152    Char2Int(Loc<&'a str>),
153    Int2Char(Loc<&'a str>),
154}
155
156pub struct ValueOperation<'a> {
157    pub name: Loc<&'a str>,
158    pub type_annotation: Option<Loc<TypeAnnotation>>,
159    pub equals_token: Loc<()>,
160    pub op: Loc<ValueOperationOp<'a>>,
161    pub semi_token: Loc<()>,
162}
163
164pub enum EffectOperationOp<'a> {
165    Jmp(Loc<Label<'a>>),
166    Br(Loc<&'a str>, Loc<Label<'a>>, Loc<Label<'a>>),
167    /// Effect-operation version.
168    Call(Loc<&'a str>, Vec<Loc<&'a str>>),
169    Ret(Option<Loc<&'a str>>),
170
171    Print(Vec<Loc<&'a str>>),
172    Nop,
173
174    Store(Loc<&'a str>, Loc<&'a str>),
175    Free(Loc<&'a str>),
176}
177
178pub struct EffectOperation<'a> {
179    pub op: Loc<EffectOperationOp<'a>>,
180    pub semi_token: Loc<()>,
181}