Skip to content

Commit 1d1caa3

Browse files
v0.17.2
1 parent 1a79943 commit 1d1caa3

7 files changed

Lines changed: 349 additions & 3 deletions

File tree

src/data/json/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
pub mod parser;
88

9-
10-
pub mod parse;
9+
// Requires the paste! macro.
10+
//pub mod parse;
1111
pub mod traits;
1212

1313

src/data/json/parse.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
11
use alloc::vec::Vec;
22
use crate::data::json::{JsonObj, JsonVal, NumVal};
33
//use crate::data::json::parser::{implementation::SimpleErr, lit, parse::{ Cat, Cat3,
4+
use crate::lit;
5+
6+
7+
lit!
8+
{
9+
pub Whitespace_Char => '\u{0020}' | '\u{000D}' | '\u{000A}' | '\u{0009}';
10+
}

src/data/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,9 @@
66
// JSON
77
pub mod json;
88

9+
10+
// Parsers
11+
pub mod parse;
12+
913
// UCS-2
1014
pub mod ucs2;

src/data/parse/json.rs

Lines changed: 330 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,330 @@
1+
use alloc::vec::Vec;
2+
use core::marker::PhantomData;
3+
4+
use crate::data::json::{JsonObj, JsonVal, NumVal};
5+
use crate::data::json::parser::implementation::{SimpleErr, SimplePos};
6+
use crate::data::json::parser::traits::{Err, Input, Pos, ResultOf};
7+
8+
9+
#[derive(Clone)]
10+
pub struct ParseOpts
11+
{
12+
pub max_nest_level: Option<u32>,
13+
}
14+
15+
impl Default for ParseOpts
16+
{
17+
fn default() -> Self
18+
{
19+
ParseOpts
20+
{
21+
max_nest_level: Some(100),
22+
}
23+
}
24+
}
25+
26+
27+
#[derive(Clone)]
28+
pub struct ParseContext
29+
{
30+
nest_level: u32,
31+
opts: ParseOpts,
32+
}
33+
34+
35+
impl ParseContext
36+
{
37+
pub fn new(opts: ParseOpts) -> Self
38+
{
39+
Self
40+
{
41+
nest_level: 0,
42+
opts,
43+
}
44+
}
45+
46+
pub fn opts(&self) -> &ParseOpts
47+
{
48+
&self.opts
49+
}
50+
51+
pub fn nest<I: Input>(&self, input: &I, pos: I::Pos) -> Result<Self, I::Err>
52+
{
53+
if Some(self.nest_level) == self.opts.max_nest_level
54+
{
55+
Err(input.err_at(pos, "[ERR] EXCEEDED NEST LEVEL"))
56+
}
57+
else
58+
{
59+
Ok(Self
60+
{
61+
nest_level: self.nest_level + 1,
62+
opts: self.opts.clone(),
63+
})
64+
}
65+
}
66+
}
67+
68+
69+
pub trait Parse<I: Input>
70+
{
71+
type Output;
72+
73+
fn parse(input: &I, current: I::Pos, context: &ParseContext) -> ResultOf<I, Self::Output>;
74+
}
75+
76+
77+
pub trait Predicate<T>
78+
{
79+
fn evaluate(t: &T) -> bool;
80+
}
81+
82+
83+
pub struct ExpectCharacter<P>(PhantomData<P>);
84+
85+
86+
impl<P: Predicate<char>, I: Input> Parse<I> for ExpectCharacter<P>
87+
{
88+
type Output = char;
89+
90+
fn parse(input: &I, current: I::Pos, _context: &ParseContext) -> ResultOf<I, Self::Output>
91+
{
92+
let (c, next) = input.next(current).map_err(|e| e.new_cause(current, "ExpectCharacter"))?;
93+
94+
if P::evaluate(&c)
95+
{
96+
Ok((c, next))
97+
}
98+
else
99+
{
100+
Err(input.err_at(current, "ExpectCharacter"))
101+
}
102+
}
103+
}
104+
105+
pub struct Null;
106+
107+
108+
impl<I: Input> Parse<I> for Null
109+
{
110+
type Output = ();
111+
112+
fn parse(_input: &I, current: I::Pos, _context: &ParseContext) -> ResultOf<I, Self::Output>
113+
{
114+
Ok(((), current))
115+
}
116+
}
117+
118+
119+
pub struct Cat<P, P2>(PhantomData<(P, P2)>);
120+
121+
122+
impl<I: Input, P: Parse<I>, P2: Parse<I>> Parse<I> for Cat<P, P2>
123+
{
124+
type Output = (P::Output, P2::Output);
125+
126+
fn parse(input: &I, current: I::Pos, context: &ParseContext) -> ResultOf<I, Self::Output>
127+
{
128+
let (output1, pos) = P::parse(input, current, context).map_err(|e| e.new_cause(current, "Cat1"))?;
129+
130+
let (output2, pos) = P2::parse(input, pos, context).map_err(|e| e.new_cause(current, "Cat2"))?;
131+
132+
Ok(((output1, output2), pos))
133+
}
134+
}
135+
136+
137+
pub type Cat3<P, P2, P3> = Cat<P, Cat<P2, P3>>;
138+
pub type Cat4<P, P2, P3, P4> = Cat<P, Cat<P2, Cat<P3, P4>>>;
139+
pub type Cat5<P, P2, P3, P4, P5> = Cat<P, Cat<P2, Cat<P3, Cat<P4, P5>>>>;
140+
141+
142+
pub enum Either<A, B>
143+
{
144+
A(A),
145+
B(B),
146+
}
147+
148+
149+
pub struct OneOf<P, P2>(PhantomData<(P, P2)>);
150+
151+
152+
impl<I: Input, P:Parse<I>, P2: Parse<I>> Parse<I> for OneOf<P, P2>
153+
{
154+
type Output = Either<P::Output, P2::Output>;
155+
156+
fn parse(input: &I, current: I::Pos, context: &ParseContext) -> ResultOf<I, Self::Output>
157+
{
158+
P::parse(input, current, context).map(|(output, pos)| (Either::A(output), pos)).or_else(|_|
159+
{
160+
P2::parse(input, current, context).map(|(output, pos)| (Either::B(output), pos))
161+
})
162+
.map_err(|e| e.new_cause(current, "OneOf"))
163+
}
164+
}
165+
166+
167+
pub type OneOf3<P, P2, P3> = OneOf<P, OneOf<P2, P3>>;
168+
pub type OneOf4<P, P2, P3, P4> = OneOf<P, OneOf3<P2, P3, P4>>;
169+
pub type OneOf5<P, P2, P3, P4, P5> = OneOf<P, OneOf4<P2, P3, P4, P5>>;
170+
pub type OneOf6<P, P2, P3, P4, P5, P6> = OneOf<P, OneOf5<P2, P3, P4, P5, P6>>;
171+
pub type OneOf7<P, P2, P3, P4, P5, P6, P7> = OneOf<P, OneOf6<P2, P3, P4, P5, P6, P7>>;
172+
pub type OneOf8<P, P2, P3, P4, P5, P6, P7, P8> = OneOf<P, OneOf7<P2, P3, P4, P5, P6, P7, P8>>;
173+
pub type OneOf9<P, P2, P3, P4, P5, P6, P7, P8, P9> = OneOf<P, OneOf8<P2, P3, P4, P5, P6, P7, P8, P9>>;
174+
175+
pub type ZeroOrOne<P> = OneOf<P, Null>;
176+
pub type ZeroOrMore<P> = OneOf<OneOrMore<P>, Null>;
177+
178+
pub struct OneOrMore<P>(PhantomData<P>);
179+
180+
181+
impl<I: Input, P: Parse<I>> Parse<I> for OneOrMore<P>
182+
{
183+
type Output = Vec<P::Output>;
184+
185+
fn parse(input: &I, current: I::Pos, context: &ParseContext) -> ResultOf<I, Self::Output>
186+
{
187+
let mut output_list = Vec::new();
188+
let (output, mut pos) = P::parse(input, current, context).map_err(|e| e.new_cause(current, "OneOrMore"))?;
189+
output_list.push(output);
190+
191+
loop
192+
{
193+
if let Ok((output, next_pos)) = P::parse(input, pos, context)
194+
{
195+
pos = next_pos;
196+
output_list.push(output);
197+
}
198+
else
199+
{
200+
return Ok((output_list, pos));
201+
}
202+
}
203+
}
204+
}
205+
206+
207+
impl Input for &str
208+
{
209+
type Pos = SimplePos;
210+
type Err = SimpleErr;
211+
212+
fn next(&self, pos: Self::Pos) -> Result<(char, Self::Pos), Self::Err>
213+
{
214+
self.chars()
215+
.nth(pos.idx() as usize)
216+
.ok_or_else(|| self.err_at(pos, "[ERR] OUT OF BOUNDS"))
217+
.map(|c| (c, pos.next(c)))
218+
}
219+
220+
fn next_range(&self, start: Self::Pos, counts: u32) -> Result<(&str, Self::Pos), Self::Err>
221+
{
222+
let startidx = start.idx() as usize;
223+
let range = startidx..startidx + counts as usize;
224+
self.get(range)
225+
.map(|s|
226+
{
227+
let mut pos = start;
228+
for c in s.chars()
229+
{
230+
pos = pos.next(c);
231+
}
232+
233+
(s, pos)
234+
})
235+
236+
.ok_or_else(|| self.err_at(start, "[ERR] OUT OF BOUNDS"))
237+
}
238+
239+
240+
fn err_at(&self, pos: Self::Pos, cause: &'static str) -> Self::Err
241+
{
242+
let mut causes = Vec::new();
243+
causes.push((pos, cause));
244+
SimpleErr
245+
{
246+
causes
247+
}
248+
}
249+
250+
251+
fn end(&self, pos: Self::Pos) -> bool
252+
{
253+
pos.idx() as usize >= self.len()
254+
}
255+
}
256+
257+
258+
259+
#[macro_export]
260+
macro_rules! lit
261+
{
262+
(
263+
$(
264+
$( #[ $attr:meta ] )*
265+
$vis:vis $name:ident => $($($value:literal)..=+)|+;
266+
)*
267+
) => {
268+
$(
269+
crate::lit!{
270+
IMPL
271+
$( #[ $attr ] )*
272+
$vis $name => $($($value)..=+)|+
273+
}
274+
)*
275+
};
276+
277+
(
278+
IMPL
279+
$( #[ $attr:meta ] )*
280+
$vis:vis $name:ident => $($($value:literal)..=+)|+
281+
) => (
282+
$crate::paste::item!
283+
{
284+
$vis struct [< $name Predicate >];
285+
impl $crate::data::parse::json::Predicate<char> for [< $name Predicate >]
286+
{
287+
fn evaluate(c: &char) -> bool
288+
{
289+
match *c
290+
{
291+
$($($value)..=+)|+ => true,
292+
_ => false
293+
}
294+
}
295+
}
296+
297+
$( #[ $attr ] )*
298+
$vis type $name = $crate::data::parse::json::ExpectCharacter<[< $name Predicate >]>;
299+
}
300+
);
301+
}
302+
303+
304+
305+
#[macro_export]
306+
macro_rules! parsers
307+
{
308+
(
309+
$(
310+
$( #[ $attr:meta ] )*
311+
$vis:vis $name:ident = $type:ty, $output_type:ty, ($output:ident) => $body:block;
312+
)*
313+
) => {
314+
$(
315+
$vis struct $name;
316+
impl<I: $crate::data::json::parser::traits::Input> $crate::data::parse::json::Parse<I> for $name
317+
{
318+
type Output = $output_type;
319+
320+
fn parse(input: &I, current: I::Pos, context: $ParseContext) -> $crate::data::json::parser::traits::ResultOf<I, Self::Output>
321+
{
322+
let ($output, pos) = <$type as $crate::data::parse::json::Parse<I>>::parse<input, current, context>
323+
.map_err(|e| <I::Err as $crate::data::json::traits::Err>::new_cause(e, current, stringify!($name)))?;
324+
let res = $body;
325+
Ok((res, pos))
326+
}
327+
}
328+
)*
329+
};
330+
}

src/data/parse/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
3+
4+
//pub mod json;

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#![no_std]
22
#![cfg_attr(test, no_main)]
33
#![allow(dead_code)]
4+
#![allow(missing_fragment_specifier)]
45
#![allow(named_asm_labels)]
56
#![allow(unused_imports)]
67
#![allow(unused_variables)]

src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ fn kernel_main(bootinfo: &'static BootInfo) -> !
3636

3737

3838
libertyos_kernel::init::start(bootinfo);
39-
println!("LIBERTYOS v0.17.1");
39+
println!("LIBERTYOS v0.17.2");
4040
print!("\x1b[?25h");
4141
println!();
4242

0 commit comments

Comments
 (0)