~starkingdoms/starkingdoms

ref: 426c4c005ea227b6953945c8bacb92575f5e392d starkingdoms/kabel/src/macros.rs -rw-r--r-- 6.7 KiB
426c4c00 — ghostly_zsh basic break and continue but it doesn't quite work 1 year, 4 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
#[macro_export]
macro_rules! token {
    ($self:expr, $token:expr) => {
        crate::lexer::Token {
            token_type: $token,
            start_column: $self.start,
            end_column: $self.line_current,
            line: $self.line,
        }
    };
}

#[macro_export]
macro_rules! token_display {
    ( $match_to:expr, $f:expr, $( $name:tt),*) => {
        match $match_to {
            $( $name => { $f.write_str(stringify!($name))?; } ),*
            _ => ()
        }
    }
}

#[macro_export]
macro_rules! lit {
    ($type:ident, $data:expr, $token:expr) => {
        $crate::parser::AST {
            ast_type: $crate::parser::ASTType::Lit($crate::parser::Lit::$type($data)),
            extensions: Vec::new(),
            start_line: $token.line,
            end_line: $token.line,
            start_column: $token.start_column,
            end_column: $token.end_column,
        }
    };
}

#[macro_export]
macro_rules! ast_from_token {
    ($ast_type:expr, $start:expr, $end:expr) => {
        $crate::parser::AST {
            ast_type: $ast_type,
            extensions: Vec::new(),
            start_line: $start.line,
            end_line: $end.line,
            start_column: $start.start_column,
            end_column: $end.end_column,
        }
    };
}
#[macro_export]
macro_rules! ast_from_token_ast {
    ($ast_type:expr, $start:expr, $end:expr) => {
        $crate::parser::AST {
            ast_type: $ast_type,
            extensions: Vec::new(),
            start_line: $start.line,
            end_line: $end.end_line,
            start_column: $start.start_column,
            end_column: $end.end_column,
        }
    };
}
#[macro_export]
macro_rules! ast_from_ast {
    ($ast_type:expr, $start:expr, $end:expr) => {
        AST {
            ast_type: $ast_type,
            extensions: Vec::new(),
            start_line: $start.start_line,
            end_line: $end.end_line,
            start_column: $start.start_column,
            end_column: $end.end_column,
        }
    };
}
#[macro_export]
macro_rules! ast_from_ast_token {
    ($ast_type:expr, $start:expr, $end:expr) => {
        AST {
            ast_type: $ast_type,
            extensions: Vec::new(),
            start_line: $start.start_line,
            end_line: $end.line,
            start_column: $start.start_column,
            end_column: $end.end_column,
        }
    };
}

#[macro_export]
macro_rules! name {
    ($name:expr, $token:expr) => {
        $crate::ast::Name {
            name: $name,
            start_column: $token.start_column,
            end_column: $token.end_column,
            line: $token.line,
        }
    };
}

#[macro_export]
macro_rules! push_output {
    ( $match_to:expr, $output:expr, $( $name:tt ),*) => {
        match $match_to {
            $( $name => { $output += stringify!($name); } ),*
        }
    }
}

#[macro_export]
macro_rules! unexpected_token {
    ($self:expr, $message:expr, $token:expr) => {
        $crate::error::KabelError::new(
            $crate::error::ErrorKind::UnexpectedToken,
            format!($message, $self.text[$token.line][$token.start_column..$token.end_column].to_string()),
            $token.line,
            $token.start_column,
            $self.text[$token.line].to_string(),
        )
    };
}

#[macro_export]
macro_rules! out_of_scope {
    ($self:expr, $message:expr, $name:expr, $expr:expr) => {
        $crate::error::KabelError::new(
            $crate::error::ErrorKind::OutOfScope,
            format!($message, $name),
            $expr.start_line,
            $expr.start_column,
            $crate::collect_lines!($self.text[$expr.start_line..$expr.end_line+1]),
        )
    };
}
#[macro_export]
macro_rules! out_of_scope_var {
    ($self:expr, $message:expr, $name:expr, $expr:expr) => {
        $crate::error::KabelError::new(
            $crate::error::ErrorKind::OutOfScope,
            format!($message, $name.name),
            $expr.start_line,
            $name.start_column,
            $crate::collect_lines!($self.text[$expr.start_line..$expr.end_line+1]),
        )
    };
}
#[macro_export]
macro_rules! mismatched_types {
    ($self:expr, $message:expr, $( $args:expr ),*) => {
        {
            let line = $self.find_line();
            $crate::runtime_error::KabelRuntimeError::new(
                $crate::runtime_error::RuntimeErrorKind::MismatchedTypes,
                format!($message, $( $args ),*),
                line,
                $self.text[line].to_string(),
            )
        }
    };
}
#[macro_export]
macro_rules! wrong_type {
    ($self:expr, $message:expr $(, $args:expr )*) => {
        {
            let line = $self.find_line();
            $crate::runtime_error::KabelRuntimeError::new(
                $crate::runtime_error::RuntimeErrorKind::WrongType,
                format!($message, $( $args ),*),
                line,
                $self.text[line].to_string(),
            )
        }
    };
}

#[macro_export]
macro_rules! collect_lines {
    ($string:expr) => {
        $string.iter().fold("".to_string(), |acc, string| acc + string + "\n").trim_end().to_string()
    };
}

#[macro_export]
macro_rules! codegen_binary {
    ($self:expr, $left:expr, $right:expr, $match_to:expr, $( $oper:tt, $code:tt ),*) => {
        match $match_to {
            $( $oper => {
                $self.visit($right);
                $self.visit($left);
                $self.vm.chunk.push(OpCode::$code.into());
                $self.vm.lines.last_mut().unwrap().1 += 1;
            } )*
        }
    };
}
#[macro_export]
macro_rules! codegen_unary {
    ($self:expr, $right:expr, $match_to:expr, $( $oper:tt, $code:tt ),*) => {
        match $match_to {
            $( $oper => {
                $self.visit($right);
                $self.vm.chunk.push(OpCode::$code.into());
                $self.vm.lines.last_mut().unwrap().1 += 1;
            } )*
        }
    };
}
#[macro_export]
macro_rules! push_codegen {
    ($match_to:expr, $vm:expr, $output:expr, $( $code:tt ), *) => {
        match $match_to {
            $( $code => {
                $output += &$vm.ip.to_string();
                $output += " ";
                $output += &$vm.find_line().to_string();
                $output += " ";
                $output += stringify!($code);
                $output += "\n";
            } )*
            _ => {}
        }
    };
}

#[macro_export]
macro_rules! vm_boolean_binary {
    ($self:expr, $oper:tt) => {
        match ($self.stack.pop().unwrap(), $self.stack.pop().unwrap()) {
            (Num(v1), Num(v2)) => $self.stack.push(Bool(v1 $oper v2)),
            (Str(v1), Str(v2)) => $self.stack.push(Bool(v1 $oper v2)),
            (Bool(v1), Bool(v2)) => $self.stack.push(Bool(v1 $oper v2)),
            (_v1, _v2) => $self.stack.push(Bool(false)),
        }
    };
}