use logicaffeine_base::Symbol;
use logicaffeine_lexicon::{Aspect, Case, Definiteness, Gender, Number, Time, VerbClass};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct Span {
pub start: usize,
pub end: usize,
}
impl Span {
pub fn new(start: usize, end: usize) -> Self {
Self { start, end }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PresupKind {
Stop,
Start,
Regret,
Continue,
Realize,
Know,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FocusKind {
Only,
Even,
Just,
Cleft,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MeasureKind {
Much,
Little,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CalendarUnit {
Second,
Minute,
Hour,
Day,
Week,
Month,
Year,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BlockType {
SuspectedTypo { found: Symbol, suggestion: Symbol },
Theorem,
Main,
Definition,
Define,
Axiom,
Theory,
Proof,
Example,
Logic,
Note,
Function,
TypeDef,
Policy,
Requires,
Hardware,
Property,
No,
Tier,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TokenType {
BlockHeader { block_type: BlockType },
All,
No,
Some,
Any,
Both, Most,
Few,
Many,
Cardinal(u32),
AtLeast(u32),
AtMost(u32),
Anything,
Anyone,
Nothing,
Nobody,
NoOne,
Nowhere,
Ever,
Never,
And,
Or,
If,
Then,
Not,
Iff,
Because,
Although,
Until,
Release,
WeakUntil,
Implies,
Must,
Shall,
Should,
Can,
May,
Cannot,
Would,
Could,
Might,
Had,
Let,
Set,
Return,
Break,
Be,
While,
Repeat,
For,
In,
From,
Assert,
Trust,
Require,
Requires,
Ensures,
Otherwise,
Else,
Elif,
Call,
New,
Either,
Inspect,
Native,
Escape,
EscapeBlock(Symbol),
Given,
Prove,
Auto,
Read,
Write,
Console,
File,
Give,
Show,
Push,
Pop,
Copy,
Through,
Length,
At,
Add,
Remove,
Contains,
Union,
Intersection,
Inside,
Zone,
Called,
Size,
Mapped,
Attempt,
Following,
Simultaneously,
Spawn,
Send,
Await,
Portable,
Manifest,
Chunk,
Shared,
Merge,
Increase,
Decrease,
Tally,
SharedSet,
SharedSequence,
CollaborativeSequence,
SharedMap,
Divergent,
Append,
Resolve,
RemoveWins,
AddWins,
YATA,
Values,
Check,
Listen,
NetConnect,
Sleep,
Sync,
Mount,
Persistent,
Combined,
Followed,
Launch,
Task,
Pipe,
Receive,
Stop,
Try,
Into,
First,
After,
Colon,
Indent,
Dedent,
Newline,
Noun(Symbol),
Adjective(Symbol),
NonIntersectiveAdjective(Symbol),
Adverb(Symbol),
ScopalAdverb(Symbol),
TemporalAdverb(Symbol),
Verb {
lemma: Symbol,
time: Time,
aspect: Aspect,
class: VerbClass,
},
ProperName(Symbol),
Ambiguous {
primary: Box<TokenType>,
alternatives: Vec<TokenType>,
},
Performative(Symbol),
Exclamation,
Article(Definiteness),
Auxiliary(Time),
Is,
Are,
Was,
Were,
That,
Who,
What,
Where,
Whose,
When,
Why,
Does,
Do,
Identity,
Equals,
Reflexive,
Reciprocal,
Respectively,
Pronoun {
gender: Gender,
number: Number,
case: Case,
},
Preposition(Symbol),
Particle(Symbol),
Comparative(Symbol),
Superlative(Symbol),
Than,
To,
PresupTrigger(PresupKind),
Focus(FocusKind),
Measure(MeasureKind),
Number(Symbol),
MoneyLiteral {
amount: Symbol,
currency: Symbol,
},
DurationLiteral {
nanos: i64,
original_unit: Symbol,
},
DateLiteral {
days: i32,
},
TimeLiteral {
nanos_from_midnight: i64,
},
CalendarUnit(CalendarUnit),
Ago,
Hence,
Before,
StringLiteral(Symbol),
InterpolatedString(Symbol),
CharLiteral(Symbol),
Item,
Items,
Possessive,
LParen,
RParen,
LBracket,
RBracket,
LBrace,
Amp,
VBar,
Tilde,
Caret,
RBrace,
Comma,
Period,
Dot,
Xor,
Shifted,
Plus,
Minus,
Star,
Slash,
Percent, PlusEq,
MinusEq,
StarEq,
SlashEq,
PercentEq,
StarStar,
SlashSlash,
Lt,
Gt,
LtEq,
GtEq,
EqEq,
NotEq,
Arrow,
Assign,
Mut,
Identifier,
EOF,
}
#[derive(Debug, Clone)]
pub struct Token {
pub kind: TokenType,
pub lexeme: Symbol,
pub span: Span,
}
impl Token {
pub fn new(kind: TokenType, lexeme: Symbol, span: Span) -> Self {
Token { kind, lexeme, span }
}
}
impl TokenType {
pub const WH_WORDS: &'static [TokenType] = &[
TokenType::Who,
TokenType::What,
TokenType::Where,
TokenType::When,
TokenType::Why,
];
pub const MODALS: &'static [TokenType] = &[
TokenType::Must,
TokenType::Shall,
TokenType::Should,
TokenType::Can,
TokenType::May,
TokenType::Cannot,
TokenType::Would,
TokenType::Could,
TokenType::Might,
];
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn span_new_stores_positions() {
let span = Span::new(5, 10);
assert_eq!(span.start, 5);
assert_eq!(span.end, 10);
}
#[test]
fn span_default_is_zero() {
let span = Span::default();
assert_eq!(span.start, 0);
assert_eq!(span.end, 0);
}
#[test]
fn token_has_span_field() {
use logicaffeine_base::Interner;
let mut interner = Interner::new();
let lexeme = interner.intern("test");
let token = Token::new(TokenType::Noun(lexeme), lexeme, Span::new(0, 4));
assert_eq!(token.span.start, 0);
assert_eq!(token.span.end, 4);
}
#[test]
fn wh_words_contains_all_wh_tokens() {
assert_eq!(TokenType::WH_WORDS.len(), 5);
assert!(TokenType::WH_WORDS.contains(&TokenType::Who));
assert!(TokenType::WH_WORDS.contains(&TokenType::What));
assert!(TokenType::WH_WORDS.contains(&TokenType::Where));
assert!(TokenType::WH_WORDS.contains(&TokenType::When));
assert!(TokenType::WH_WORDS.contains(&TokenType::Why));
}
#[test]
fn modals_contains_all_modal_tokens() {
assert_eq!(TokenType::MODALS.len(), 9);
assert!(TokenType::MODALS.contains(&TokenType::Must));
assert!(TokenType::MODALS.contains(&TokenType::Shall));
assert!(TokenType::MODALS.contains(&TokenType::Should));
assert!(TokenType::MODALS.contains(&TokenType::Can));
assert!(TokenType::MODALS.contains(&TokenType::May));
assert!(TokenType::MODALS.contains(&TokenType::Cannot));
assert!(TokenType::MODALS.contains(&TokenType::Would));
assert!(TokenType::MODALS.contains(&TokenType::Could));
assert!(TokenType::MODALS.contains(&TokenType::Might));
}
}