Actually just three programming languages in a trenchcoat
1use crate::{Parser, Spanned};
2use source_span::Span;
3use trilogy_scanner::{Token, TokenType::*};
4
5#[derive(Clone, Debug)]
6pub struct KeywordReference {
7 pub open_paren: Token,
8 pub keyword: Keyword,
9 pub close_paren: Token,
10 pub span: Span,
11}
12
13impl Spanned for KeywordReference {
14 fn span(&self) -> Span {
15 self.span
16 }
17}
18
19#[derive(Clone, Debug, Spanned)]
20pub enum Keyword {
21 Access(Token),
22 And(Token),
23 Or(Token),
24 Add(Token),
25 Subtract(Token),
26 Multiply(Token),
27 Divide(Token),
28 Remainder(Token),
29 Power(Token),
30 IntDivide(Token),
31 StructuralEquality(Token),
32 ReferenceEquality(Token),
33 StructuralInequality(Token),
34 ReferenceInequality(Token),
35 Lt(Token),
36 Gt(Token),
37 Leq(Token),
38 Geq(Token),
39 BitwiseAnd(Token),
40 BitwiseOr(Token),
41 BitwiseXor(Token),
42 LeftShift(Token),
43 RightShift(Token),
44 LeftShiftExtend(Token),
45 RightShiftExtend(Token),
46 LeftShiftContract(Token),
47 RightShiftContract(Token),
48 Cons(Token),
49 Glue(Token),
50 Compose(Token),
51 RCompose(Token),
52 Pipe(Token),
53 RPipe(Token),
54 Not(Token),
55 Invert(Token),
56 Yield(Token),
57 Resume(Token),
58 Cancel(Token),
59 Return(Token),
60 Break(Token),
61 Continue(Token),
62 Typeof(Token),
63}
64
65impl KeywordReference {
66 pub(crate) fn try_parse(parser: &mut Parser) -> Option<Self> {
67 let tokens = parser.peekn(3)?;
68 if tokens[0].token_type != OParen || tokens[2].token_type != CParen {
69 return None;
70 }
71 let constructor = match tokens[1].token_type {
72 OpDot => Keyword::Access,
73 OpBang => Keyword::Not,
74 OpTilde => Keyword::Invert,
75 KwYield => Keyword::Yield,
76 OpAmpAmp => Keyword::And,
77 OpPipePipe => Keyword::Or,
78 OpPlus => Keyword::Add,
79 OpMinus => Keyword::Subtract,
80 OpStar => Keyword::Multiply,
81 OpSlash => Keyword::Divide,
82 OpSlashSlash => Keyword::IntDivide,
83 OpPercent => Keyword::Remainder,
84 OpStarStar => Keyword::Power,
85 OpEqEq => Keyword::StructuralEquality,
86 OpBangEq => Keyword::StructuralInequality,
87 OpEqEqEq => Keyword::ReferenceEquality,
88 OpBangEqEq => Keyword::ReferenceInequality,
89 OpLt => Keyword::Lt,
90 OpGt => Keyword::Gt,
91 OpLtEq => Keyword::Leq,
92 OpGtEq => Keyword::Geq,
93 OpAmp => Keyword::BitwiseAnd,
94 OpPipe => Keyword::BitwiseOr,
95 OpCaret => Keyword::BitwiseXor,
96 OpShl => Keyword::LeftShift,
97 OpShr => Keyword::RightShift,
98 OpShlEx => Keyword::LeftShiftExtend,
99 OpShrEx => Keyword::RightShiftExtend,
100 OpShlCon => Keyword::LeftShiftContract,
101 OpShrCon => Keyword::RightShiftContract,
102 OpColon => Keyword::Cons,
103 OpGlue => Keyword::Glue,
104 OpLtLt => Keyword::Compose,
105 OpGtGt => Keyword::RCompose,
106 OpPipeGt => Keyword::Pipe,
107 OpLtPipe => Keyword::RPipe,
108 KwBreak => Keyword::Break,
109 KwContinue => Keyword::Continue,
110 KwResume => Keyword::Resume,
111 KwCancel => Keyword::Cancel,
112 KwReturn => Keyword::Return,
113 KwTypeof => Keyword::Typeof,
114 _ => return None,
115 };
116 let open_paren = parser.consume();
117 let keyword = constructor(parser.consume());
118 let close_paren = parser.consume();
119 Some(Self {
120 span: open_paren.span.union(close_paren.span),
121 open_paren,
122 keyword,
123 close_paren,
124 })
125 }
126}