bibleparsing/
parse.rs

1// Part of speech bits 1-5
2pub const UNKNOWN: u32 = 0;
3pub const PARTICLE: u32 = 1;
4pub const VERB: u32 = 2;
5pub const NOUN: u32 = 3;
6pub const ADJECTIVE: u32 = 4;
7pub const ADVERB: u32 = 5;
8pub const CONJUNCTION: u32 = 6;
9pub const PROPER_NOUN: u32 = 7;
10pub const PREPOSITION: u32 = 8;
11pub const CONDITIONAL: u32 = 9;
12pub const ARTICLE: u32 = 10;
13pub const INTERJECTION: u32 = 11;
14pub const PRONOUN: u32 = 12;
15pub const PERSONAL_PRONOUN: u32 = 13;
16pub const POSSESSIVE_PRONOUN: u32 = 14;
17pub const RELATIVE_PRONOUN: u32 = 15;
18pub const DEMONSTRATIVE_PRONOUN: u32 = 16;
19pub const RECIPROCAL_PRONOUN: u32 = 17;
20pub const REFLEXIVE_PRONOUN: u32 = 18;
21pub const TRANSLITERATION: u32 = 19;
22pub const HEBREW_TRANSLITERATION: u32 = 20;
23pub const ARAMAIC_TRANSLITERATION: u32 = 21;
24pub const LETTER: u32 = 22;
25pub const NUMERAL: u32 = 23;
26pub const SUPERLATIVE_ADJECTIVE: u32 = 24;
27pub const SUPERLATIVE_ADVERB: u32 = 25;
28pub const SUPERLATIVE_NOUN: u32 = 26;
29pub const COMPARATIVE_ADJECTIVE: u32 = 27;
30pub const COMPARATIVE_ADVERB: u32 = 28;
31pub const COMPARATIVE_NOUN: u32 = 29;
32
33pub fn part_of_speech(p: u32) -> u32 {
34    p & 0b11111
35}
36
37pub fn set_part_of_speech(p: u32, pos: u32) -> u32 {
38    let mask = !0b11111;
39    (p & mask) | pos
40}
41
42// Flags that modify part of speech, bits 6-11
43pub const INTERROGATIVE: u32 = 1 << 6;
44pub const NEGATIVE: u32 = 1 << 7;
45pub const CORRELATIVE: u32 = 1 << 8;
46pub const INDEFINITE: u32 = 1 << 9;
47pub const INDECLINABLE: u32 = 1 << 10;
48pub const CRASIS: u32 = 1 << 11;
49
50pub fn is_interrogative(p: u32) -> bool {
51    p & INTERROGATIVE == INTERROGATIVE
52}
53
54pub fn is_negative(p: u32) -> bool {
55    p & NEGATIVE == NEGATIVE
56}
57
58pub fn is_correlative(p: u32) -> bool {
59    p & CORRELATIVE == CORRELATIVE
60}
61
62pub fn is_indefinite(p: u32) -> bool {
63    p & INDEFINITE == INDEFINITE
64}
65
66pub fn is_indeclinable(p: u32) -> bool {
67    p & INDECLINABLE == INDECLINABLE
68}
69
70pub fn is_crasis(p: u32) -> bool {
71    p & CRASIS == CRASIS
72}
73
74// Tense form, 4 bits. Bits 12-15
75pub const PRESENT: u32 = 1 << 12;
76pub const FUTURE: u32 = 2 << 12;
77pub const AORIST: u32 = 3 << 12;
78pub const IMPERFECT: u32 = 4 << 12;
79pub const PERFECT: u32 = 5 << 12;
80pub const PLUPERFECT: u32 = 6 << 12;
81pub const SECOND_FUTURE: u32 = 7 << 12;
82pub const SECOND_AORIST: u32 = 8 << 12;
83pub const SECOND_PERFECT: u32 = 9 << 12;
84pub const SECOND_PLUPERFECT: u32 = 10 << 12;
85
86pub fn tense(p: u32) -> u32 {
87    p & (0b1111 << 12)
88}
89
90// Tense form bits are overloaded to hold
91// data for non verbs
92pub const REF_SINGULAR: u32 = 0 << 12;
93pub const REF_PLURAL: u32 = 1 << 12;
94
95pub fn ref_number(p: u32) -> u32 {
96    p & (0b1 << 12)
97}
98
99// Gender, 3 bits, 16-18
100pub const MASCULINE: u32 = 1 << 16;
101pub const FEMININE: u32 = 2 << 16;
102pub const NEUTER: u32 = 4 << 16;
103
104pub fn gender(p: u32) -> u32 {
105    p & (0b111 << 16)
106}
107
108// Case, 3 bits, 19-21
109pub const NOMINATIVE: u32 = 1 << 19;
110pub const ACCUSATIVE: u32 = 2 << 19;
111pub const GENITIVE: u32 = 3 << 19;
112pub const DATIVE: u32 = 4 << 19;
113pub const VOCATIVE: u32 = 5 << 19;
114
115pub fn case(p: u32) -> u32 {
116    p & (0b111 << 19)
117}
118
119// Voice, 3 bits, 22-24
120pub const ACTIVE_VOICE: u32 = 1 << 22;
121pub const MIDDLE_VOICE: u32 = 2 << 22;
122pub const PASSIVE_VOICE: u32 = 3 << 22;
123pub const MIDDLE_PASSIVE_VOICE: u32 = 4 << 22;
124pub const MIDDLE_DEPONENT_VOICE: u32 = 5 << 22;
125pub const PASSIVE_DEPONENT_VOICE: u32 = 6 << 22;
126pub const MIDDLE_PASSIVE_DEPONENT_VOICE: u32 = 7 << 22;
127
128pub fn voice(p: u32) -> u32 {
129    p & (0b111 << 22)
130}
131
132// Mood, 3 bits, 25-27
133pub const INDICATIVE_MOOD: u32 = 1 << 25;
134pub const SUBJUNCTIVE_MOOD: u32 = 2 << 25;
135pub const OPTATIVE_MOOD: u32 = 3 << 25;
136pub const IMPERATIVE_MOOD: u32 = 4 << 25;
137pub const INFINITIVE_MOOD: u32 = 5 << 25;
138pub const PARTICIPLE_MOOD: u32 = 6 << 25;
139
140pub fn mood(p: u32) -> u32 {
141    p & (0b111 << 25)
142}
143
144// Person, 2 bits, 28-29
145pub const FIRST_PERSON: u32 = 1 << 28;
146pub const SECOND_PERSON: u32 = 2 << 28;
147pub const THIRD_PERSON: u32 = 3 << 28;
148
149pub fn person(p: u32) -> u32 {
150    p & (0b11 << 28)
151}
152
153// Number, 2 bits, 30-31
154pub const SINGULAR: u32 = 1 << 30;
155pub const DUAL: u32 = 2 << 30;
156pub const PLURAL: u32 = 3 << 30;
157
158pub fn number(p: u32) -> u32 {
159    p & (0b11 << 30)
160}
161
162#[cfg(test)]
163mod tests {
164    use super::*;
165
166    #[test]
167    fn test_parsing_bits() {
168        assert_eq!(gender(MASCULINE | NOMINATIVE), MASCULINE);
169        assert_eq!(gender(FEMININE | NOMINATIVE), FEMININE);
170        assert_eq!(gender(NEUTER | NOMINATIVE), NEUTER);
171        assert_eq!(gender(MASCULINE | ACCUSATIVE), MASCULINE);
172        assert_eq!(gender(FEMININE | ACCUSATIVE), FEMININE);
173        assert_eq!(gender(NEUTER | ACCUSATIVE), NEUTER);
174        assert_eq!(gender(MASCULINE | GENITIVE), MASCULINE);
175        assert_eq!(gender(FEMININE | GENITIVE), FEMININE);
176        assert_eq!(gender(NEUTER | GENITIVE), NEUTER);
177
178        assert_eq!(case(MASCULINE | NOMINATIVE), NOMINATIVE);
179        assert_eq!(case(FEMININE | NOMINATIVE), NOMINATIVE);
180        assert_eq!(case(NEUTER | NOMINATIVE), NOMINATIVE);
181        assert_eq!(case(MASCULINE | ACCUSATIVE), ACCUSATIVE);
182        assert_eq!(case(FEMININE | ACCUSATIVE), ACCUSATIVE);
183        assert_eq!(case(NEUTER | ACCUSATIVE), ACCUSATIVE);
184        assert_eq!(case(MASCULINE | GENITIVE), GENITIVE);
185        assert_eq!(case(FEMININE | GENITIVE), GENITIVE);
186        assert_eq!(case(NEUTER | GENITIVE), GENITIVE);
187
188        let parsed = DEMONSTRATIVE_PRONOUN | ACCUSATIVE | PLURAL | NEUTER;
189        assert_eq!(is_crasis(parsed), false);
190        assert_eq!(case(parsed), ACCUSATIVE);
191        assert_eq!(number(parsed), PLURAL);
192        assert_eq!(gender(parsed), NEUTER);
193        assert_eq!(part_of_speech(parsed), DEMONSTRATIVE_PRONOUN);
194        let parsed = parsed | CRASIS;
195        assert_eq!(is_crasis(parsed), true);
196        assert_eq!(case(parsed), ACCUSATIVE);
197        assert_eq!(number(parsed), PLURAL);
198        assert_eq!(gender(parsed), NEUTER);
199        assert_eq!(part_of_speech(parsed), DEMONSTRATIVE_PRONOUN);
200        assert_eq!(
201            parsed,
202            DEMONSTRATIVE_PRONOUN | ACCUSATIVE | PLURAL | NEUTER | CRASIS
203        );
204
205        let parsed = COMPARATIVE_ADJECTIVE | INTERROGATIVE;
206        assert_eq!(is_crasis(parsed), false);
207        assert_eq!(is_interrogative(parsed), true);
208
209        let parsed = COMPARATIVE_NOUN | INTERROGATIVE;
210        assert_eq!(is_crasis(parsed), false);
211        assert_eq!(is_interrogative(parsed), true);
212        assert_eq!(part_of_speech(parsed), COMPARATIVE_NOUN);
213    }
214
215    #[test]
216    fn test_set_part_of_speech() {
217        let parsed = NOUN; // == 3
218        let out = set_part_of_speech(parsed, VERB); // == 2
219        assert_eq!(part_of_speech(out), VERB, "hmmm {} {}", parsed, out);
220
221        let parsed = ADJECTIVE;
222        let out = set_part_of_speech(parsed, SUPERLATIVE_ADJECTIVE);
223        assert_eq!(
224            part_of_speech(out),
225            SUPERLATIVE_ADJECTIVE,
226            "hmmm {} {}",
227            parsed,
228            out
229        );
230    }
231}