Skip to main content

blues_lsp/syntax/lexer/
token.rs

1use std::fmt::Display;
2
3use arcstr::Substr;
4
5use crate::syntax::location::Span;
6
7#[derive(Debug, Clone)]
8pub struct Token {
9    pub span: Span,
10    pub kind: TokenKind,
11}
12
13#[derive(Debug, Clone)]
14pub enum TokenKind {
15    /// Keywords
16    Kw(Kw),
17    /// Identifiers
18    Ident(Substr),
19    /// System identifiers ('$foo')
20    SysIdent(Substr),
21    /// Symbols
22    Sym(Sym),
23    /// Numeric literals
24    Num(NumLit),
25    /// String literals
26    Str(Substr),
27    // Note: we don't really have a need to represent the actual values, yet.
28    /// Comments
29    Comment,
30    /// Error placeholder
31    Error,
32}
33
34impl TokenKind {
35    pub fn significant(&self) -> bool {
36        !matches!(self, TokenKind::Comment | TokenKind::Error)
37    }
38
39    pub fn ident(&self) -> Option<&Substr> {
40        match self {
41            TokenKind::Ident(substr) => Some(substr),
42            _ => None,
43        }
44    }
45}
46
47impl Display for TokenKind {
48    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49        match self {
50            TokenKind::Kw(kw) => write!(f, "keyword '{kw}'"),
51            TokenKind::Ident(ident) => write!(f, "identifier '{ident}'"),
52            TokenKind::SysIdent(ident) => write!(f, "system identifier '{ident}'"),
53            TokenKind::Sym(sym) => write!(f, "symbol '{sym}'"),
54            TokenKind::Num(NumLit::Int) => write!(f, "integer number"),
55            TokenKind::Num(NumLit::Mixed) => write!(f, "mixed number"),
56            TokenKind::Num(NumLit::Real) => write!(f, "real number"),
57            TokenKind::Num(NumLit::Repeated) => write!(f, "repeated bit number"),
58            TokenKind::Str(_) => write!(f, "string"),
59            TokenKind::Comment => write!(f, "comment"),
60            TokenKind::Error => write!(f, "error token"),
61        }
62    }
63}
64
65macro_rules! kw_list {
66    ($(($name:ident, $string:literal, $doc:literal),)*) => {
67        #[derive(Debug, Clone, Copy, PartialEq, Eq)]
68        pub enum Kw {
69            $(#[doc=$doc] $name,)*
70            __Last
71        }
72
73        const KWS: &[(Kw, &'static str)]= &[
74            $((Kw::$name, $string),)*
75        ];
76
77        impl Display for Kw {
78            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79                match self {
80                    $(Kw::$name => f.write_str($string),)*
81                    Kw::__Last => unreachable!()
82                }
83            }
84        }
85    };
86}
87
88impl Kw {
89    pub fn parse(s: &str) -> Option<Kw> {
90        // TODO: this could do with a trie or smth
91        KWS.iter().find(|k| k.1 == s).map(|k| k.0)
92    }
93}
94
95// https://github.com/B-Lang-org/bsc/blob/a798d8a94d54197d2b4755afdbb460cdc559c151/src/comp/SystemVerilogKeywords.lhs#L379
96// BSV keywords moved to front.
97#[rustfmt::skip]
98kw_list![
99    (Action,                 "action",                  "`action`"),
100    (Endaction,              "endaction",               "`endaction`"),
101    (Actionvalue,            "actionvalue",             "`actionvalue`"),
102    (Endactionvalue,         "endactionvalue",          "`endactionvalue`"),
103    (Deriving,               "deriving",                "`deriving`"),
104    (Endinstance,            "endinstance",             "`endinstance`"),
105    (Let,                    "let",                     "`let`"),
106    (Method,                 "method",                  "`method`"),
107    (Endmethod,              "endmethod",               "`endmethod`"),
108    (Par,                    "par",                     "`par`"),
109    (Endpar,                 "endpar",                  "`endpar`"),
110    (Abortif,                "abortif",                 "`abortif`"),
111    (Provisos,               "provisos",                "`provisos`"),
112    (Rule,                   "rule",                    "`rule`"),
113    (Endrule,                "endrule",                 "`endrule`"),
114    (Rules,                  "rules",                   "`rules`"),
115    (Endrules,               "endrules",                "`endrules`"),
116    (Seq,                    "seq",                     "`seq`"),
117    (Endseq,                 "endseq",                  "`endseq`"),
118    (Goto,                   "goto",                    "`goto`"),
119    (Typeclass,              "typeclass",               "`typeclass`"),
120    (Endtypeclass,           "endtypeclass",            "`endtypeclass`"),
121    (Valueof,                "valueof",                 "`valueof`"),
122    (ValueOf,                "valueOf",                 "`valueOf`"),
123    (Stringof,               "stringof",                "`stringof`"),
124    (StringOf,               "stringOf",                "`stringOf`"),
125    (ClockedBy,              "clocked_by",              "`clocked_by`"),
126    (ResetBy,                "reset_by",                "`reset_by`"),
127    (PoweredBy,              "powered_by",              "`powered_by`"),
128    (ActionType,             "Action",                  "`Action`"),
129    (ActionValueType,        "ActionValue",             "`ActionValue`"),
130    (Alias,                  "alias",                   "`alias`"),
131    (Always,                 "always",                  "`always`"),
132    (AlwaysComb,             "always_comb",             "`always_comb`"),
133    (AlwaysFf,               "always_ff",               "`always_ff`"),
134    (AlwaysLatch,            "always_latch",            "`always_latch`"),
135    (And,                    "and",                     "`and`"),
136    (Assert,                 "assert",                  "`assert`"),
137    (AssertStrobe,           "assert_strobe",           "`assert_strobe`"),
138    (Assign,                 "assign",                  "`assign`"),
139    (Assume,                 "assume",                  "`assume`"),
140    (Automatic,              "automatic",               "`automatic`"),
141    (Before,                 "before",                  "`before`"),
142    (Begin,                  "begin",                   "`begin`"),
143    (Bind,                   "bind",                    "`bind`"),
144    (Bins,                   "bins",                    "`bins`"),
145    (Binsof,                 "binsof",                  "`binsof`"),
146    (Bit,                    "bit",                     "`bit`"),
147    (Break,                  "break",                   "`break`"),
148    (Buf,                    "buf",                     "`buf`"),
149    (Bufif0,                 "bufif0",                  "`bufif0`"),
150    (Bufif1,                 "bufif1",                  "`bufif1`"),
151    (Byte,                   "byte",                    "`byte`"),
152    (Case,                   "case",                    "`case`"),
153    (Casex,                  "casex",                   "`casex`"),
154    (Casez,                  "casez",                   "`casez`"),
155    (Cell,                   "cell",                    "`cell`"),
156    (Chandle,                "chandle",                 "`chandle`"),
157    (Class,                  "class",                   "`class`"),
158    (Clocking,               "clocking",                "`clocking`"),
159    (Cmos,                   "cmos",                    "`cmos`"),
160    (Config,                 "config",                  "`config`"),
161    (Const,                  "const",                   "`const`"),
162    (Constraint,             "constraint",              "`constraint`"),
163    (Context,                "context",                 "`context`"),
164    (Continue,               "continue",                "`continue`"),
165    (Cover,                  "cover",                   "`cover`"),
166    (Covergroup,             "covergroup",              "`covergroup`"),
167    (Coverpoint,             "coverpoint",              "`coverpoint`"),
168    (Cross,                  "cross",                   "`cross`"),
169    (Deassign,               "deassign",                "`deassign`"),
170    (Default,                "default",                 "`default`"),
171    (Defparam,               "defparam",                "`defparam`"),
172    (Design,                 "design",                  "`design`"),
173    (Disable,                "disable",                 "`disable`"),
174    (Dist,                   "dist",                    "`dist`"),
175    (Do,                     "do",                      "`do`"),
176    (Edge,                   "edge",                    "`edge`"),
177    (Else,                   "else",                    "`else`"),
178    (End,                    "end",                     "`end`"),
179    (Endcase,                "endcase",                 "`endcase`"),
180    (Endclass,               "endclass",                "`endclass`"),
181    (Endclocking,            "endclocking",             "`endclocking`"),
182    (Endconfig,              "endconfig",               "`endconfig`"),
183    (Endfunction,            "endfunction",             "`endfunction`"),
184    (Endgenerate,            "endgenerate",             "`endgenerate`"),
185    (Endgroup,               "endgroup",                "`endgroup`"),
186    (Endinterface,           "endinterface",            "`endinterface`"),
187    (Endmodule,              "endmodule",               "`endmodule`"),
188    (Endpackage,             "endpackage",              "`endpackage`"),
189    (Endprimitive,           "endprimitive",            "`endprimitive`"),
190    (Endprogram,             "endprogram",              "`endprogram`"),
191    (Endproperty,            "endproperty",             "`endproperty`"),
192    (Endspecify,             "endspecify",              "`endspecify`"),
193    (Endsequence,            "endsequence",             "`endsequence`"),
194    (Endtable,               "endtable",                "`endtable`"),
195    (Endtask,                "endtask",                 "`endtask`"),
196    (Enum,                   "enum",                    "`enum`"),
197    (Event,                  "event",                   "`event`"),
198    (Expect,                 "expect",                  "`expect`"),
199    (Export,                 "export",                  "`export`"),
200    (Extends,                "extends",                 "`extends`"),
201    (Extern,                 "extern",                  "`extern`"),
202    (Final,                  "final",                   "`final`"),
203    (FirstMatch,             "first_match",             "`first_match`"),
204    (For,                    "for",                     "`for`"),
205    (Force,                  "force",                   "`force`"),
206    (Foreach,                "foreach",                 "`foreach`"),
207    (Forever,                "forever",                 "`forever`"),
208    (Fork,                   "fork",                    "`fork`"),
209    (Forkjoin,               "forkjoin",                "`forkjoin`"),
210    (Function,               "function",                "`function`"),
211    (Generate,               "generate",                "`generate`"),
212    (Genvar,                 "genvar",                  "`genvar`"),
213    (Highz0,                 "highz0",                  "`highz0`"),
214    (Highz1,                 "highz1",                  "`highz1`"),
215    (If,                     "if",                      "`if`"),
216    (Iff,                    "iff",                     "`iff`"),
217    (Ifnone,                 "ifnone",                  "`ifnone`"),
218    (IgnoreBins,             "ignore_bins",             "`ignore_bins`"),
219    (IllegalBins,            "illegal_bins",            "`illegal_bins`"),
220    (Import,                 "import",                  "`import`"),
221    (Incdir,                 "incdir",                  "`incdir`"),
222    (Include,                "include",                 "`include`"),
223    (Initial,                "initial",                 "`initial`"),
224    (Inout,                  "inout",                   "`inout`"),
225    (Input,                  "input",                   "`input`"),
226    (Inside,                 "inside",                  "`inside`"),
227    (Instance,               "instance",                "`instance`"),
228    (Int,                    "int",                     "`int`"),
229    (Integer,                "integer",                 "`integer`"),
230    (Interface,              "interface",               "`interface`"),
231    (Intersect,              "intersect",               "`intersect`"),
232    (Join,                   "join",                    "`join`"),
233    (JoinAny,                "join_any",                "`join_any`"),
234    (JoinNone,               "join_none",               "`join_none`"),
235    (Large,                  "large",                   "`large`"),
236    (Liblist,                "liblist",                 "`liblist`"),
237    (Library,                "library",                 "`library`"),
238    (Local,                  "local",                   "`local`"),
239    (Localparam,             "localparam",              "`localparam`"),
240    (Logic,                  "logic",                   "`logic`"),
241    (Longint,                "longint",                 "`longint`"),
242    (Macromodule,            "macromodule",             "`macromodule`"),
243    (Match,                  "match",                   "`match`"),
244    (Matches,                "matches",                 "`matches`"),
245    (Medium,                 "medium",                  "`medium`"),
246    (Modport,                "modport",                 "`modport`"),
247    (Module,                 "module",                  "`module`"),
248    (Nand,                   "nand",                    "`nand`"),
249    (Negedge,                "negedge",                 "`negedge`"),
250    (New,                    "new",                     "`new`"),
251    (Nmos,                   "nmos",                    "`nmos`"),
252    (Nor,                    "nor",                     "`nor`"),
253    (Noshowcancelled,        "noshowcancelled",         "`noshowcancelled`"),
254    (Not,                    "not",                     "`not`"),
255    (Notif0,                 "notif0",                  "`notif0`"),
256    (Notif1,                 "notif1",                  "`notif1`"),
257    (Null,                   "null",                    "`null`"),
258    (Or,                     "or",                      "`or`"),
259    (Output,                 "output",                  "`output`"),
260    (Package,                "package",                 "`package`"),
261    (Packed,                 "packed",                  "`packed`"),
262    (Parameter,              "parameter",               "`parameter`"),
263    (Pmos,                   "pmos",                    "`pmos`"),
264    (Posedge,                "posedge",                 "`posedge`"),
265    (Primitive,              "primitive",               "`primitive`"),
266    (Priority,               "priority",                "`priority`"),
267    (Program,                "program",                 "`program`"),
268    (Property,               "property",                "`property`"),
269    (Protected,              "protected",               "`protected`"),
270    (Pull0,                  "pull0",                   "`pull0`"),
271    (Pull1,                  "pull1",                   "`pull1`"),
272    (Pulldown,               "pulldown",                "`pulldown`"),
273    (Pullup,                 "pullup",                  "`pullup`"),
274    (PulsestyleOnevent,      "pulsestyle_onevent",      "`pulsestyle_onevent`"),
275    (PulsestyleOndetect,     "pulsestyle_ondetect",     "`pulsestyle_ondetect`"),
276    (Pure,                   "pure",                    "`pure`"),
277    (Rand,                   "rand",                    "`rand`"),
278    (Randc,                  "randc",                   "`randc`"),
279    (Randcase,               "randcase",                "`randcase`"),
280    (Randsequence,           "randsequence",            "`randsequence`"),
281    (Rcmos,                  "rcmos",                   "`rcmos`"),
282    (Real,                   "real",                    "`real`"),
283    (Realtime,               "realtime",                "`realtime`"),
284    (Ref,                    "ref",                     "`ref`"),
285    (Reg,                    "reg",                     "`reg`"),
286    (Release,                "release",                 "`release`"),
287    (Repeat,                 "repeat",                  "`repeat`"),
288    (Return,                 "return",                  "`return`"),
289    (Rnmos,                  "rnmos",                   "`rnmos`"),
290    (Rpmos,                  "rpmos",                   "`rpmos`"),
291    (Rtran,                  "rtran",                   "`rtran`"),
292    (Rtranif0,               "rtranif0",                "`rtranif0`"),
293    (Rtranif1,               "rtranif1",                "`rtranif1`"),
294    (Scalared,               "scalared",                "`scalared`"),
295    (Sequence,               "sequence",                "`sequence`"),
296    (Shortint,               "shortint",                "`shortint`"),
297    (Shortreal,              "shortreal",               "`shortreal`"),
298    (Showcancelled,          "showcancelled",           "`showcancelled`"),
299    (Signed,                 "signed",                  "`signed`"),
300    (Small,                  "small",                   "`small`"),
301    (Solve,                  "solve",                   "`solve`"),
302    (Specify,                "specify",                 "`specify`"),
303    (Specparam,              "specparam",               "`specparam`"),
304    (Static,                 "static",                  "`static`"),
305    (String,                 "string",                  "`string`"),
306    (Strong0,                "strong0",                 "`strong0`"),
307    (Strong1,                "strong1",                 "`strong1`"),
308    (Struct,                 "struct",                  "`struct`"),
309    (Super,                  "super",                   "`super`"),
310    (Supply0,                "supply0",                 "`supply0`"),
311    (Supply1,                "supply1",                 "`supply1`"),
312    (Table,                  "table",                   "`table`"),
313    (Tagged,                 "tagged",                  "`tagged`"),
314    (Task,                   "task",                    "`task`"),
315    (This,                   "this",                    "`this`"),
316    (Throughout,             "throughout",              "`throughout`"),
317    (Time,                   "time",                    "`time`"),
318    (Timeprecision,          "timeprecision",           "`timeprecision`"),
319    (Timeunit,               "timeunit",                "`timeunit`"),
320    (Tran,                   "tran",                    "`tran`"),
321    (Tranif0,                "tranif0",                 "`tranif0`"),
322    (Tranif1,                "tranif1",                 "`tranif1`"),
323    (Tri,                    "tri",                     "`tri`"),
324    (Tri0,                   "tri0",                    "`tri0`"),
325    (Tri1,                   "tri1",                    "`tri1`"),
326    (Triand,                 "triand",                  "`triand`"),
327    (Trior,                  "trior",                   "`trior`"),
328    (Trireg,                 "trireg",                  "`trireg`"),
329    (Type,                   "type",                    "`type`"),
330    (Typedef,                "typedef",                 "`typedef`"),
331    (Union,                  "union",                   "`union`"),
332    (Unique,                 "unique",                  "`unique`"),
333    (Unsigned,               "unsigned",                "`unsigned`"),
334    (Use,                    "use",                     "`use`"),
335    (Var,                    "var",                     "`var`"),
336    (Vectored,               "vectored",                "`vectored`"),
337    (Virtual,                "virtual",                 "`virtual`"),
338    (Void,                   "void",                    "`void`"),
339    (Wait,                   "wait",                    "`wait`"),
340    (WaitOrder,              "wait_order",              "`wait_order`"),
341    (Wand,                   "wand",                    "`wand`"),
342    (Weak0,                  "weak0",                   "`weak0`"),
343    (Weak1,                  "weak1",                   "`weak1`"),
344    (While,                  "while",                   "`while`"),
345    (Wildcard,               "wildcard",                "`wildcard`"),
346    (Wire,                   "wire",                    "`wire`"),
347    (With,                   "with",                    "`with`"),
348    (Within,                 "within",                  "`within`"),
349    (Wor,                    "wor",                     "`wor`"),
350    (Xnor,                   "xnor",                    "`xnor`"),
351    (Xor,                    "xor",                     "`xor`"),
352];
353
354macro_rules! sym_list {
355    ($(($name:ident, $string:literal, $doc:literal),)*) => {
356        #[derive(Debug, Clone, Copy, PartialEq, Eq)]
357        pub enum Sym {
358            $(#[doc=$doc] $name,)*
359        }
360
361        const SYMS: &[(Sym, &'static str)]= &[
362            $((Sym::$name, $string),)*
363        ];
364
365        impl Display for Sym {
366            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
367                match self {
368                    $(Sym::$name => f.write_str($string),)*
369                }
370            }
371        }
372    };
373}
374
375impl Sym {
376    pub fn longest_match(str: &str) -> Option<(Sym, &'static str)> {
377        // SYMS are sorted by length descending, so first match is guaranteed to be the longest.
378        SYMS.iter().find(|(_, sym)| str.starts_with(sym)).copied()
379    }
380}
381
382// https://github.com/B-Lang-org/bsc/blob/a798d8a94d54197d2b4755afdbb460cdc559c151/src/comp/SystemVerilogKeywords.lhs#L642
383// *MUST* be sorted by length descending
384#[rustfmt::skip]
385sym_list![
386    ( LtLtLtEq,           "<<<=",      "`<<<=`" ),
387    ( GtGtGtEq,           ">>>=",      "`>>>=`" ),
388    ( BangEqEq,           "!==",       "`!==`"  ),
389    ( BangQuestionEq,     "!?=",       "`!?=`"  ),
390    ( EtEtEt,             "&&&",       "`&&&`"  ),
391    ( LtLtLt,             "<<<",       "`<<<`"  ),
392    ( LtLtEq,             "<<=",       "`<<=`"  ),
393    ( EqEqEq,             "===",       "`===`"  ),
394    ( EqQuestionEq,       "=?=",       "`=?=`"  ),
395    ( GtGtEq,             ">>=",       "`>>=`"  ),
396    ( GtGtGt,             ">>>",       "`>>>`"  ),
397    ( LbracketMinusGt,    "[->",       "`[->`"  ),
398    ( PipeMinusGt,        "|->",       "`|->`"  ),
399    ( PipeEqGt,           "|=>",       "`|=>`"  ),
400    ( BangEq,             "!=",        "`!=`"   ),
401    ( HashHash,           "##",        "`##`"   ),
402    ( PercentEq,          "%=",        "`%=`"   ),
403    ( EtEt,               "&&",        "`&&`"   ),
404    ( EtEq,               "&=",        "`&=`"   ),
405    ( LparenStar,         "(*",        "`(*`"   ),
406    ( StarRparen,         "*)",        "`*)`"   ),
407    ( StarStar,           "**",        "`**`"   ),
408    ( PlusPlus,           "++",        "`++`"   ),
409    ( PlusEq,             "+=",        "`+=`"   ),
410    ( MinusMinus,         "--",        "`--`"   ),
411    ( MinusEq,            "-=",        "`-=`"   ),
412    ( MinusGt,            "->",        "`->`"   ),
413    ( DotStar,            ".*",        "`.*`"   ),
414    ( DotDot,             "..",        "`..`"   ),
415    ( SlashEq,            "/=",        "`/=`"   ),
416    ( ColonColon,         "::",        "`::`"   ),
417    ( LtMinus,            "<-",        "`<-`"   ),
418    ( LtLt,               "<<",        "`<<`"   ),
419    ( LtEq,               "<=",        "`<=`"   ),
420    ( LtGt,               "<>",        "`<>`"   ),
421    ( EqEq,               "==",        "`==`"   ),
422    ( GtEq,               ">=",        "`>=`"   ),
423    ( GtGt,               ">>",        "`>>`"   ),
424    ( LbracketStar,       "[*",        "`[*`"   ),
425    ( LbracketEq,         "[=",        "`[=`"   ),
426    ( CaretEq,            "^=",        "`^=`"   ),
427    ( CaretTilde,         "^~",        "`^~`"   ),
428    ( PipeEq,             "|=",        "`|=`"   ),
429    ( PipePipe,           "||",        "`||`"   ),
430    ( TildeEt,            "~&",        "`~&`"   ),
431    ( TildeCaret,         "~^",        "`~^`"   ),
432    ( TildePipe,          "~|",        "`~|`"   ),
433    ( Bang,               "!",         "`!`"    ),
434    ( Hash,               "#",         "`#`"    ),
435    ( Dollar,             "$",         "`$`"    ),
436    ( Percent,            "%",         "`%`"    ),
437    ( Et,                 "&",         "`&`"    ),
438    ( Tick,               "'",         "`'`"    ),
439    ( Lparen,             "(",         "`(`"    ),
440    ( Rparen,             ")",         "`)`"    ),
441    ( Star,               "*",         "`*`"    ),
442    ( Plus,               "+",         "`+`"    ),
443    ( Comma,              ",",         "`,`"    ),
444    ( Minus,              "-",         "`-`"    ),
445    ( Dot,                ".",         "`.`"    ),
446    ( Slash,              "/",         "`/`"    ),
447    ( Colon,              ":",         "`:`"    ),
448    ( Semi,               ";",         "`;`"    ),
449    ( Lt,                 "<",         "`<`"    ),
450    ( Eq,                 "=",         "`=`"    ),
451    ( Gt,                 ">",         "`>`"    ),
452    ( Question,           "?",         "`?`"    ),
453    ( Lbracket,           "[",         "`[`"    ),
454    ( Rbracket,           "]",         "`]`"    ),
455    ( Caret,              "^",         "`^`"    ),
456    ( Backtick,           "`",         "```"    ),
457    ( Lbrace,             "{",         "`{`"    ),
458    ( Pipe,               "|",         "`|`"    ),
459    ( Rbrace,             "}",         "`}`"    ),
460    ( Tilde,              "~",         "`~`"    ),
461];
462
463/// Numeric literal
464#[derive(Debug, Clone, Copy, PartialEq, Eq)]
465pub enum NumLit {
466    /// Integer
467    Int,
468    /// Real (64-bit IEEE)
469    Real,
470    /// Repeated bit pattern
471    Repeated,
472    /// Mixed, includes 'X' and 'Z' bits
473    Mixed,
474}
475
476#[derive(Debug, Clone, Copy, PartialEq, Eq)]
477pub enum Bit {
478    Zero,
479    One,
480    Undef,
481    HighZ,
482    DontCare,
483}
484
485impl Bit {
486    pub fn parse(c: char) -> Option<Self> {
487        match c {
488            '0' => Some(Self::Zero),
489            '1' => Some(Self::One),
490            'x' | 'X' => Some(Self::Undef),
491            'z' | 'Z' => Some(Self::HighZ),
492            '?' => Some(Self::DontCare),
493            _ => None,
494        }
495    }
496}