|
| 1 | +use crate::ir::IrPat; |
1 | 2 | use crate::ir_interpreter::IrInterpreter;
|
2 | 3 | use crate::ir_value::IrValue;
|
3 | 4 | use crate::{CompileError, ParseError, Spanned};
|
|
7 | 8 | mod ir_binary;
|
8 | 9 | mod ir_branches;
|
9 | 10 | mod ir_break;
|
| 11 | +mod ir_condition; |
10 | 12 | mod ir_decl;
|
11 | 13 | mod ir_loop;
|
12 | 14 | mod ir_object;
|
@@ -34,18 +36,33 @@ impl Used {
|
34 | 36 | }
|
35 | 37 |
|
36 | 38 | pub(crate) trait Eval<T> {
|
| 39 | + type Output; |
| 40 | + |
37 | 41 | /// Evaluate the given type.
|
38 |
| - fn eval(&mut self, value: T, used: Used) -> Result<IrValue, EvalOutcome>; |
| 42 | + fn eval(&mut self, value: T, used: Used) -> Result<Self::Output, EvalOutcome>; |
39 | 43 | }
|
40 | 44 |
|
41 | 45 | pub(crate) trait ConstAs {
|
42 | 46 | /// Process constant value as a boolean.
|
43 | 47 | fn as_bool(self, compiler: &mut IrInterpreter<'_>, used: Used) -> Result<bool, EvalOutcome>;
|
44 | 48 | }
|
45 | 49 |
|
| 50 | +pub(crate) trait Matches { |
| 51 | + /// Test if the current trait matches the given value. |
| 52 | + fn matches<S>( |
| 53 | + &self, |
| 54 | + compiler: &mut IrInterpreter<'_>, |
| 55 | + value: IrValue, |
| 56 | + used: Used, |
| 57 | + spanned: S, |
| 58 | + ) -> Result<bool, EvalOutcome> |
| 59 | + where |
| 60 | + S: Spanned; |
| 61 | +} |
| 62 | + |
46 | 63 | impl<T> ConstAs for T
|
47 | 64 | where
|
48 |
| - for<'a> IrInterpreter<'a>: Eval<T>, |
| 65 | + for<'a> IrInterpreter<'a>: Eval<T, Output = IrValue>, |
49 | 66 | T: Spanned,
|
50 | 67 | {
|
51 | 68 | fn as_bool(self, compiler: &mut IrInterpreter<'_>, used: Used) -> Result<bool, EvalOutcome> {
|
|
60 | 77 | }
|
61 | 78 | }
|
62 | 79 |
|
| 80 | +impl Matches for IrPat { |
| 81 | + fn matches<S>( |
| 82 | + &self, |
| 83 | + compiler: &mut IrInterpreter<'_>, |
| 84 | + value: IrValue, |
| 85 | + used: Used, |
| 86 | + spanned: S, |
| 87 | + ) -> Result<bool, EvalOutcome> |
| 88 | + where |
| 89 | + S: Spanned, |
| 90 | + { |
| 91 | + match self { |
| 92 | + IrPat::Ignore => Ok(true), |
| 93 | + IrPat::Binding(name) => { |
| 94 | + compiler.scopes.decl(name, value, spanned)?; |
| 95 | + Ok(true) |
| 96 | + } |
| 97 | + } |
| 98 | + } |
| 99 | +} |
| 100 | + |
63 | 101 | pub(crate) enum EvalOutcome {
|
64 | 102 | /// Encountered ast that is not a constant expression.
|
65 | 103 | NotConst(Span),
|
|
0 commit comments