Skip to main content

litex/stmt/
define_algorithm_stmt.rs

1use crate::prelude::*;
2use std::fmt;
3
4// algo f(a, b):
5//     case a > b: a
6//     case a <= b: b
7#[derive(Clone)]
8pub struct DefAlgoStmt {
9    pub name: String,
10    pub params: Vec<String>,
11    pub default_return: Option<AlgoReturn>,
12    pub cases: Vec<AlgoCase>,
13    pub line_file: LineFile,
14}
15
16#[derive(Clone)]
17pub struct AlgoReturn {
18    pub value: Obj,
19    pub line_file: LineFile,
20}
21#[derive(Clone)]
22pub struct AlgoCase {
23    pub condition: AtomicFact, // 只有 atomic fact 能reverse,而 algo case 有可能需要被reverse掉(处理 default_return 的时候)。
24    pub return_stmt: AlgoReturn,
25    pub line_file: LineFile,
26}
27
28#[derive(Clone)]
29pub enum AlgoReturnOrAlgoCase {
30    AlgoReturn(AlgoReturn),
31    AlgoCase(AlgoCase),
32}
33
34impl DefAlgoStmt {
35    pub fn new(
36        name: String,
37        params: Vec<String>,
38        cases: Vec<AlgoCase>,
39        default_return: Option<AlgoReturn>,
40        line_file: LineFile,
41    ) -> Self {
42        DefAlgoStmt {
43            name,
44            params,
45            default_return,
46            cases,
47            line_file,
48        }
49    }
50}
51
52impl fmt::Display for AlgoReturnOrAlgoCase {
53    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54        match self {
55            AlgoReturnOrAlgoCase::AlgoReturn(algo_return) => write!(f, "{}", algo_return),
56            AlgoReturnOrAlgoCase::AlgoCase(algo_case) => write!(f, "{}", algo_case),
57        }
58    }
59}
60
61impl fmt::Display for AlgoReturn {
62    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63        write!(f, "{}", (&self.value))
64    }
65}
66
67impl fmt::Display for AlgoCase {
68    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69        write!(
70            f,
71            "{} {}{} {}",
72            CASE,
73            self.condition,
74            COLON,
75            add_four_spaces_at_beginning(self.return_stmt.to_string(), 1)
76        )
77    }
78}
79
80impl fmt::Display for DefAlgoStmt {
81    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82        if let Some(default_return) = &self.default_return {
83            write!(
84                f,
85                "{} {}{}{}\n{}\n{}",
86                ALGO,
87                self.name,
88                braced_vec_to_string(&self.params),
89                COLON,
90                to_string_and_add_four_spaces_at_beginning_of_each_line(
91                    &vec_to_string_with_sep(&self.cases, "\n".to_string()),
92                    1
93                ),
94                default_return
95            )
96        } else {
97            write!(
98                f,
99                "{} {}{}{}\n{}",
100                ALGO,
101                self.name,
102                braced_vec_to_string(&self.params),
103                COLON,
104                to_string_and_add_four_spaces_at_beginning_of_each_line(
105                    &vec_to_string_with_sep(&self.cases, "\n".to_string()),
106                    1
107                )
108            )
109        }
110    }
111}
112
113impl AlgoReturn {
114    pub fn new(value: Obj, line_file: LineFile) -> Self {
115        AlgoReturn { value, line_file }
116    }
117}
118
119impl AlgoCase {
120    pub fn new(condition: AtomicFact, return_stmt: AlgoReturn, line_file: LineFile) -> Self {
121        AlgoCase {
122            condition,
123            return_stmt,
124            line_file,
125        }
126    }
127}
128
129impl AlgoReturnOrAlgoCase {
130    pub fn line_file(&self) -> LineFile {
131        match self {
132            AlgoReturnOrAlgoCase::AlgoReturn(algo_return) => algo_return.line_file.clone(),
133            AlgoReturnOrAlgoCase::AlgoCase(algo_case) => algo_case.line_file.clone(),
134        }
135    }
136}