Skip to main content

intent_lang_syntax/
lexer.rs

1use logos::Logos;
2
3#[derive(Logos, Debug, Clone, PartialEq)]
4#[logos(skip r"[ \t\r\n\f]+")]
5#[logos(skip r"//[^\n]*")]
6pub enum Token {
7    // ── Keywords ─────────────────────────────────────────
8    #[token("type")]
9    Type,
10    #[token("enum")]
11    Enum,
12    #[token("intent")]
13    Intent,
14    #[token("safety")]
15    Safety,
16    #[token("theorem")]
17    Theorem,
18    #[token("axiom")]
19    Axiom,
20    #[token("function")]
21    Function,
22    #[token("import")]
23    Import,
24    #[token("require")]
25    Require,
26    #[token("ensure")]
27    Ensure,
28    #[token("invariant")]
29    Invariant,
30    #[token("forall")]
31    Forall,
32    #[token("exists")]
33    Exists,
34    #[token("if")]
35    If,
36    #[token("then")]
37    Then,
38    #[token("else")]
39    Else,
40    #[token("true")]
41    True,
42    #[token("false")]
43    False,
44    #[token("after")]
45    After,
46    #[token("as")]
47    As,
48
49    // ── Requirements-modeling keywords (RFC: A1, A3) ─────
50    #[token("goal")]
51    Goal,
52    #[token("rationale")]
53    Rationale,
54    #[token("stakeholder")]
55    Stakeholder,
56    #[token("measure")]
57    Measure,
58    #[token("realized_by")]
59    RealizedBy,
60    #[token("coverage")]
61    Coverage,
62    #[token("dimensions")]
63    Dimensions,
64
65    // ── Symbols ──────────────────────────────────────────
66    #[token("{")]
67    LBrace,
68    #[token("}")]
69    RBrace,
70    #[token("(")]
71    LParen,
72    #[token(")")]
73    RParen,
74    #[token("[")]
75    LBracket,
76    #[token("]")]
77    RBracket,
78    #[token("<")]
79    Lt,
80    #[token(">")]
81    Gt,
82    #[token(",")]
83    Comma,
84    #[token(".")]
85    Dot,
86    #[token(":")]
87    Colon,
88    #[token("->")]
89    Arrow,
90    #[token("@")]
91    At,
92    #[token("'")]
93    Prime,
94
95    // ── Operators ────────────────────────────────────────
96    #[token("==>")]
97    Implies,
98    #[token("==")]
99    EqEq,
100    #[token("!=")]
101    BangEq,
102    #[token("<=")]
103    LtEq,
104    #[token(">=")]
105    GtEq,
106    #[token("&&")]
107    AmpAmp,
108    #[token("||")]
109    PipePipe,
110    #[token("+")]
111    Plus,
112    #[token("-")]
113    Minus,
114    #[token("*")]
115    Star,
116    #[token("/")]
117    Slash,
118    #[token("%")]
119    Percent,
120    #[token("!")]
121    Bang,
122
123    // ── Literals ─────────────────────────────────────────
124    #[regex(r"[0-9]+", |lex| lex.slice().parse::<i64>().ok())]
125    IntLit(i64),
126
127    #[regex(r#""([^"\\]|\\.)*""#, |lex| {
128        let s = lex.slice();
129        Some(s[1..s.len()-1].to_string())
130    })]
131    StringLit(String),
132
133    // ── Identifiers ──────────────────────────────────────
134    #[regex(r"[a-zA-Z_][a-zA-Z0-9_]*", |lex| lex.slice().to_string(), priority = 1)]
135    Ident(String),
136}
137
138impl std::fmt::Display for Token {
139    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
140        match self {
141            Token::Type => write!(f, "type"),
142            Token::Enum => write!(f, "enum"),
143            Token::Intent => write!(f, "intent"),
144            Token::Safety => write!(f, "safety"),
145            Token::Theorem => write!(f, "theorem"),
146            Token::Axiom => write!(f, "axiom"),
147            Token::Function => write!(f, "function"),
148            Token::Import => write!(f, "import"),
149            Token::Require => write!(f, "require"),
150            Token::Ensure => write!(f, "ensure"),
151            Token::Invariant => write!(f, "invariant"),
152            Token::Forall => write!(f, "forall"),
153            Token::Exists => write!(f, "exists"),
154            Token::If => write!(f, "if"),
155            Token::Then => write!(f, "then"),
156            Token::Else => write!(f, "else"),
157            Token::True => write!(f, "true"),
158            Token::False => write!(f, "false"),
159            Token::After => write!(f, "after"),
160            Token::As => write!(f, "as"),
161            Token::Goal => write!(f, "goal"),
162            Token::Rationale => write!(f, "rationale"),
163            Token::Stakeholder => write!(f, "stakeholder"),
164            Token::Measure => write!(f, "measure"),
165            Token::RealizedBy => write!(f, "realized_by"),
166            Token::Coverage => write!(f, "coverage"),
167            Token::Dimensions => write!(f, "dimensions"),
168            Token::LBrace => write!(f, "{{"),
169            Token::RBrace => write!(f, "}}"),
170            Token::LParen => write!(f, "("),
171            Token::RParen => write!(f, ")"),
172            Token::LBracket => write!(f, "["),
173            Token::RBracket => write!(f, "]"),
174            Token::Lt => write!(f, "<"),
175            Token::Gt => write!(f, ">"),
176            Token::Comma => write!(f, ","),
177            Token::Dot => write!(f, "."),
178            Token::Colon => write!(f, ":"),
179            Token::Arrow => write!(f, "->"),
180            Token::At => write!(f, "@"),
181            Token::Prime => write!(f, "'"),
182            Token::Implies => write!(f, "==>"),
183            Token::EqEq => write!(f, "=="),
184            Token::BangEq => write!(f, "!="),
185            Token::LtEq => write!(f, "<="),
186            Token::GtEq => write!(f, ">="),
187            Token::AmpAmp => write!(f, "&&"),
188            Token::PipePipe => write!(f, "||"),
189            Token::Plus => write!(f, "+"),
190            Token::Minus => write!(f, "-"),
191            Token::Star => write!(f, "*"),
192            Token::Slash => write!(f, "/"),
193            Token::Percent => write!(f, "%"),
194            Token::Bang => write!(f, "!"),
195            Token::IntLit(v) => write!(f, "{v}"),
196            Token::StringLit(s) => write!(f, "\"{s}\""),
197            Token::Ident(s) => write!(f, "{s}"),
198        }
199    }
200}