summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/error.rs45
-rw-r--r--src/lexer.rs6
-rw-r--r--src/lib.rs27
-rw-r--r--src/parser.rs221
4 files changed, 158 insertions, 141 deletions
diff --git a/src/error.rs b/src/error.rs
new file mode 100644
index 0000000..a2b6d96
--- /dev/null
+++ b/src/error.rs
@@ -0,0 +1,45 @@
1
2use core::error::Error;
3use std::fmt;
4
5use crate::position::*;
6
7#[derive(Debug)]
8pub struct CrimError {
9 position: Position,
10 what: String,
11}
12
13impl CrimError {
14 pub fn new( position: Position, what: String ) -> Self {
15 CrimError {
16 position,
17 what,
18 }
19 }
20
21 pub fn eos( context: &str ) -> Self {
22 CrimError {
23 position: Position::none(),
24 what: format!("Premature end of stream while looking for {}", context),
25 }
26 }
27
28 pub fn what(&self) -> &str {
29 &self.what
30 }
31
32 pub fn start(&self) -> &Position {
33 &self.position
34 }
35}
36
37impl fmt::Display for CrimError {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39 write!(f, "Error parsing input: {}", "yeah")
40 }
41}
42
43impl Error for CrimError { }
44
45pub type CrimResult<T> = Result<T, CrimError>;
diff --git a/src/lexer.rs b/src/lexer.rs
index 7228866..2fa29ce 100644
--- a/src/lexer.rs
+++ b/src/lexer.rs
@@ -22,6 +22,9 @@ pub enum SymbolType<'a> {
22 Loop, 22 Loop,
23 Equals, 23 Equals,
24 Period, 24 Period,
25 If,
26 ElseIf,
27 Else,
25 Token(&'a str), 28 Token(&'a str),
26 Literal(&'a str), 29 Literal(&'a str),
27 Text(&'a str), 30 Text(&'a str),
@@ -246,6 +249,9 @@ impl<'a> Lexer<'a> {
246 "show" => SymbolType::Show, 249 "show" => SymbolType::Show,
247 "output" => SymbolType::Output, 250 "output" => SymbolType::Output,
248 "loop" => SymbolType::Loop, 251 "loop" => SymbolType::Loop,
252 "if" => SymbolType::If,
253 "elseif" => SymbolType::ElseIf,
254 "else" => SymbolType::Else,
249 _ => SymbolType::Token(s) 255 _ => SymbolType::Token(s)
250 }, start_pos, end_pos )) 256 }, start_pos, end_pos ))
251 } 257 }
diff --git a/src/lib.rs b/src/lib.rs
index feb00f0..9b838f3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -6,8 +6,9 @@ use std::time::SystemTime;
6mod lexer; 6mod lexer;
7mod parser; 7mod parser;
8mod position; 8mod position;
9mod error;
9 10
10pub use parser::ParseError; 11pub use error::{CrimError,CrimResult};
11pub use position::*; 12pub use position::*;
12 13
13#[derive(Debug)] 14#[derive(Debug)]
@@ -38,7 +39,7 @@ struct View {
38} 39}
39 40
40impl View { 41impl View {
41 fn process(&self, input: &impl MappedStructure) -> Result<Context, ParseError> { 42 fn process(&self, input: &impl MappedStructure) -> Result<Context, CrimError> {
42 let mut out_vars = Context::new(); 43 let mut out_vars = Context::new();
43 for output in &self.outputs { 44 for output in &self.outputs {
44 let mut buf = String::new(); 45 let mut buf = String::new();
@@ -61,6 +62,9 @@ type Properties = HashMap<String, String>;
61enum Token { 62enum Token {
62 Loop(Identifier, Vec<Token>), 63 Loop(Identifier, Vec<Token>),
63 Show(Identifier,Properties), 64 Show(Identifier,Properties),
65 If(Identifier, Vec<Token>),
66 ElseIf(Identifier, Vec<Token>),
67 Else(Vec<Token>),
64 Text(String), 68 Text(String),
65} 69}
66 70
@@ -165,13 +169,13 @@ impl Crimtag {
165 Ok(()) 169 Ok(())
166 } 170 }
167 171
168 pub fn load_static(&mut self, data: &str) -> Result<(),ParseError> { 172 pub fn load_static(&mut self, data: &str) -> Result<(),CrimError> {
169 let source_id = self.id_source( &ViewSource::Static ); 173 let source_id = self.id_source( &ViewSource::Static );
170 let p = parser::Parser::new(); 174 let p = parser::Parser::new();
171 self.register_views( p.parse( &data, source_id )? ) 175 self.register_views( p.parse( &data, source_id )? )
172 } 176 }
173 177
174 pub fn load_external(&mut self, key: &str, data: &str) -> Result<(),ParseError> { 178 pub fn load_external(&mut self, key: &str, data: &str) -> Result<(),CrimError> {
175 let source_id = self.id_source( 179 let source_id = self.id_source(
176 &ViewSource::External{ key: key.to_string()} 180 &ViewSource::External{ key: key.to_string()}
177 ); 181 );
@@ -182,7 +186,7 @@ impl Crimtag {
182 ) 186 )
183 } 187 }
184 188
185 fn register_views(&mut self, views: Vec<View>) -> Result<(),ParseError> { 189 fn register_views(&mut self, views: Vec<View>) -> Result<(),CrimError> {
186 for view in views { 190 for view in views {
187 self.views.insert( view.name.clone(), view ); 191 self.views.insert( view.name.clone(), view );
188 } 192 }
@@ -201,15 +205,15 @@ impl Crimtag {
201 } 205 }
202 } 206 }
203 207
204 pub fn render_partial(&self, view: &str, input: &impl MappedStructure ) -> Result<Context,ParseError> { 208 pub fn render_partial(&self, view: &str, input: &impl MappedStructure ) -> Result<Context,CrimError> {
205 if let Some(view) = self.views.get(view) { 209 if let Some(view) = self.views.get(view) {
206 return view.process( input ) 210 return view.process( input )
207 } else { 211 } else {
208 return Err(ParseError::new(Position::new(0,0),"No such view found")); 212 return Err(CrimError::new(Position::none(),"No such view found".into()));
209 } 213 }
210 } 214 }
211 215
212 pub fn render(&self, view: &str, input: &impl MappedStructure ) -> Result<String,ParseError> { 216 pub fn render(&self, view: &str, input: &impl MappedStructure ) -> Result<String,CrimError> {
213 if let Some(view) = self.views.get( view ) { 217 if let Some(view) = self.views.get( view ) {
214 let mut output = view.process( input )?; 218 let mut output = view.process( input )?;
215 if let Some(l) = &view.layout { 219 if let Some(l) = &view.layout {
@@ -220,17 +224,17 @@ impl Crimtag {
220 224
221 Ok(s) 225 Ok(s)
222 } else { 226 } else {
223 Err(ParseError::new(Position::new(0,0),"No content found in root layout.")) 227 Err(CrimError::new(Position::none(), "No content found in root layout.".into()))
224 } 228 }
225 } 229 }
226 230
227 } else { 231 } else {
228 Err(ParseError::new(Position::new(0,0),"No such view found")) 232 Err(CrimError::new(Position::none(),"No such view found".into()))
229 } 233 }
230 } 234 }
231} 235}
232 236
233fn exec(input: &impl MappedStructure, tokens: &Vec<Token>, buf: &mut String) -> Result<(),ParseError> { 237fn exec(input: &impl MappedStructure, tokens: &Vec<Token>, buf: &mut String) -> Result<(),CrimError> {
234 for token in tokens { 238 for token in tokens {
235 match token { 239 match token {
236 Token::Loop(ident,code) => { 240 Token::Loop(ident,code) => {
@@ -279,6 +283,7 @@ fn exec(input: &impl MappedStructure, tokens: &Vec<Token>, buf: &mut String) ->
279 Token::Text(s) => { 283 Token::Text(s) => {
280 buf.push_str( s ); 284 buf.push_str( s );
281 } 285 }
286 _ => {}
282 } 287 }
283 } 288 }
284 Ok(()) 289 Ok(())
diff --git a/src/parser.rs b/src/parser.rs
index 07bbd93..83144fb 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -1,41 +1,6 @@
1use crate::lexer::*; 1use crate::lexer::*;
2use crate::*; 2use crate::*;
3 3
4use core::error::Error;
5use std::fmt;
6
7#[derive(Debug)]
8pub struct ParseError {
9 position: Position,
10 what: String,
11}
12
13impl ParseError {
14 pub fn new( position: Position, what: &str ) -> Self {
15 ParseError {
16 position,
17 what: what.to_string(),
18 }
19 }
20
21 pub fn eos( context: &str ) -> Self {
22 ParseError {
23 position: Position::none(),
24 what: format!("Premature end of stream while looking for {}", context),
25 }
26 }
27}
28
29impl fmt::Display for ParseError {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 write!(f, "Error parsing input: {}", "yeah")
32 }
33}
34
35impl Error for ParseError { }
36
37pub type ParseResult<T> = Result<T, ParseError>;
38
39struct Context<'a> { 4struct Context<'a> {
40 cur: [Option<Symbol<'a>>;2], 5 cur: [Option<Symbol<'a>>;2],
41 icur: usize, 6 icur: usize,
@@ -70,9 +35,9 @@ impl<'a> Context<'a> {
70 self.cur[(self.icur+1)%2] 35 self.cur[(self.icur+1)%2]
71 } 36 }
72 37
73 pub fn check_unwrapped<T: Fn( &SymbolType, &SymbolType ) -> bool>(&self, context: &str, f: T) -> ParseResult<bool> { 38 pub fn check_unwrapped<T: Fn( &SymbolType, &SymbolType ) -> bool>(&self, context: &str, f: T) -> CrimResult<bool> {
74 if self.cur().is_none() || self.peek().is_none() { 39 if self.cur().is_none() || self.peek().is_none() {
75 Err(ParseError::eos( context )) 40 Err(CrimError::eos( context ))
76 } else { 41 } else {
77 Ok(f( self.cur().unwrap().symbol(), self.peek().unwrap().symbol())) 42 Ok(f( self.cur().unwrap().symbol(), self.peek().unwrap().symbol()))
78 } 43 }
@@ -84,34 +49,37 @@ impl<'a> Context<'a> {
84} 49}
85 50
86trait SymbolHelper { 51trait SymbolHelper {
87 fn is<T: Fn( &SymbolType ) -> bool>(&self, context: &str, f: T ) -> ParseResult<bool>; 52 fn is<T: Fn( &SymbolType ) -> bool>(&self, context: &str, f: T ) -> CrimResult<bool>;
88 fn is_valid_tag_name(&self) -> ParseResult<bool>; 53 fn is_valid_tag_name(&self) -> CrimResult<bool>;
89} 54}
90 55
91impl<'a> SymbolHelper for Option<Symbol<'a>> { 56impl<'a> SymbolHelper for Option<Symbol<'a>> {
92 fn is<T: Fn( &SymbolType ) -> bool>(&self, context: &str, f: T ) -> ParseResult<bool> { 57 fn is<T: Fn( &SymbolType ) -> bool>(&self, context: &str, f: T ) -> CrimResult<bool> {
93 if let Some(st) = self { 58 if let Some(st) = self {
94 Ok(f( &st.symbol() )) 59 Ok(f( &st.symbol() ))
95 } else { 60 } else {
96 Err(ParseError::eos( context )) 61 Err(CrimError::eos( context ))
97 } 62 }
98 } 63 }
99 64
100 fn is_valid_tag_name(&self) -> ParseResult<bool> { 65 fn is_valid_tag_name(&self) -> CrimResult<bool> {
101 if let Some(st) = self { 66 if let Some(st) = self {
102 Ok(match st.symbol() { 67 Ok(match st.symbol() {
103 SymbolType::Token(_) | 68 SymbolType::Token(_) |
104 SymbolType::View | 69 SymbolType::View |
105 SymbolType::Output | 70 SymbolType::Output |
106 SymbolType::Loop | 71 SymbolType::Loop |
72 SymbolType::If |
73 SymbolType::ElseIf |
74 SymbolType::Else |
107 SymbolType::Show => true, 75 SymbolType::Show => true,
108 _ => false 76 _ => false
109 }) 77 })
110 } else { 78 } else {
111 Err(ParseError{ 79 Err(CrimError::new(
112 position: Position::new(0,0), 80 Position::none(),
113 what: "Unexpeceted end of stream.".to_string() 81 "Unexpeceted end of stream.".to_string()
114 }) 82 ))
115 } 83 }
116 } 84 }
117} 85}
@@ -202,21 +170,17 @@ impl Parser {
202 } 170 }
203 } 171 }
204 172
205 fn lex_error<T>(&self, error: &Symbol) -> ParseResult<T> { 173 fn lex_error<T>(&self, error: &Symbol) -> CrimResult<T> {
206 if let SymbolType::Error{what} = error.symbol() { 174 if let SymbolType::Error{what} = error.symbol() {
207 Err(ParseError { 175 Err(CrimError::new( *error.start(),
208 position: error.start().clone(), 176 format!("What: {:?}", *what)
209 what: format!("What: {:?}", *what) 177 ))
210 })
211 } else { 178 } else {
212 Err(ParseError { 179 Err(CrimError::new( Position::none(), "Not an error?".into()))
213 position: Position::new(0,0),
214 what: "Not an error?".to_string(),
215 })
216 } 180 }
217 } 181 }
218 182
219 pub fn parse(&self, src: &str, source: usize ) -> ParseResult<Vec<View>> { 183 pub fn parse(&self, src: &str, source: usize ) -> CrimResult<Vec<View>> {
220 let ll = Lexer::new( src ); 184 let ll = Lexer::new( src );
221 let mut ctx = Context::new( ll, source ); 185 let mut ctx = Context::new( ll, source );
222 186
@@ -224,7 +188,7 @@ impl Parser {
224 self.p_input( &mut ctx ) 188 self.p_input( &mut ctx )
225 } 189 }
226 190
227 fn p_input(&self, ctx: &mut Context ) -> ParseResult<Vec<View>> { 191 fn p_input(&self, ctx: &mut Context ) -> CrimResult<Vec<View>> {
228 let mut children = Vec::new(); 192 let mut children = Vec::new();
229 loop { 193 loop {
230 if ctx.cur().is_none() { 194 if ctx.cur().is_none() {
@@ -247,13 +211,12 @@ impl Parser {
247 Ok(children) 211 Ok(children)
248 } 212 }
249 213
250 fn parse_tag_view(&self, ctx: &mut Context) -> ParseResult<View> { 214 fn parse_tag_view(&self, ctx: &mut Context) -> CrimResult<View> {
251 let tb = self.parse_open_tag( ctx )?; 215 let tb = self.parse_open_tag( ctx )?;
252 if !tb.is_name( &SymbolType::View ) { 216 if !tb.is_name( &SymbolType::View ) {
253 return Err(ParseError{ 217 return Err(CrimError::new(tb.start_pos(),
254 position: tb.start_pos(), 218 "Unexpected tag type, only frament allowed at root".into()
255 what: "Unexpected tag type, only frament allowed at root".to_string(), 219 ));
256 });
257 } 220 }
258 221
259 if tb.is_unary() { 222 if tb.is_unary() {
@@ -265,7 +228,7 @@ impl Parser {
265 //println!("--parse-tag-view-- tag parsed, next token: {:?}", ctx.cur() ); 228 //println!("--parse-tag-view-- tag parsed, next token: {:?}", ctx.cur() );
266 loop { 229 loop {
267 if ctx.cur().is_none() { 230 if ctx.cur().is_none() {
268 return Err(ParseError::eos(format!("close tag for {:?}", tb.name()).as_str())) 231 return Err(CrimError::eos(format!("close tag for {:?}", tb.name()).as_str()))
269 } 232 }
270 match ctx.cur().unwrap().symbol() { 233 match ctx.cur().unwrap().symbol() {
271 SymbolType::Text(s) => { 234 SymbolType::Text(s) => {
@@ -297,52 +260,56 @@ impl Parser {
297 }); 260 });
298 } else { 261 } else {
299 if !all_text { 262 if !all_text {
300 return Err(ParseError{ 263 return Err(CrimError::new(
301 position: *end.start(), 264 *end.start(),
302 what: "You cannot mix non-output and output tags in a view.".to_string() 265 "You cannot mix non-output and output tags in a view.".to_string()
303 }); 266 ));
304 } 267 }
305 } 268 }
306 return tb.build_view(ctx,outputs); 269 return tb.build_view(ctx,outputs);
307 } else { 270 } else {
308 // They don't match, complain. 271 // They don't match, complain.
309 return Err(ParseError{ 272 return Err(CrimError::new(
310 position: *end.start(), 273 *end.start(),
311 what: "Mismatched open and closing tags.".to_string() 274 "Mismatched open and closing tags.".to_string()
312 }); 275 ));
313 } 276 }
314 } 277 }
315 SymbolType::Error{..} => { 278 SymbolType::Error{..} => {
316 return self.lex_error( &ctx.cur().unwrap() ); 279 return self.lex_error( &ctx.cur().unwrap() );
317 } 280 }
318 _ => { 281 _ => {
319 return Err(ParseError{ 282 return Err(CrimError::new(
320 position: *ctx.cur().unwrap().start(), 283 *ctx.cur().unwrap().start(),
321 what: format!("Unexpected tag in view root: {:?}", ctx.cur().unwrap().symbol()) 284 format!("Unexpected tag in view root: {:?}", ctx.cur().unwrap().symbol())
322 }); 285 ));
323 } 286 }
324 } 287 }
325 } 288 }
326 } 289 }
327 290
328 fn parse_open_tag<'a>(&self, ctx: &mut Context<'a>) -> ParseResult<TagBuilder<'a>> { 291 fn parse_open_tag<'a>(&self, ctx: &mut Context<'a>) -> CrimResult<TagBuilder<'a>> {
329 let start_sym = ctx.cur().unwrap(); 292 let start_sym = ctx.cur().unwrap();
330 let mut tb = TagBuilder::new(&start_sym); 293 let mut tb = TagBuilder::new(&start_sym);
331 294
332 if ctx.next().is_some() { 295 if ctx.next().is_some() {
333 match ctx.cur().unwrap().symbol() { 296 match ctx.cur().unwrap().symbol() {
334 SymbolType::View | SymbolType::Show | SymbolType::Loop | 297 SymbolType::View | SymbolType::Show | SymbolType::Loop |
298 SymbolType::If | SymbolType::ElseIf | SymbolType::Else |
335 SymbolType::Output => { 299 SymbolType::Output => {
336 let name_sym = ctx.cur().unwrap(); 300 let name_sym = ctx.cur().unwrap();
337 ctx.next(); 301 ctx.next();
338 tb.set_name( name_sym ); 302 tb.set_name( name_sym );
339 } 303 }
340 _ => { 304 _ => {
341 return Err(ParseError{position: ctx.cur().unwrap().start().clone(), what: "Unexpected symbol".to_string()}); 305 return Err(CrimError::new(
306 *ctx.cur().unwrap().start(),
307 "Unexpected symbol".to_string()
308 ));
342 } 309 }
343 } 310 }
344 } else { 311 } else {
345 return Err(ParseError::eos("tag type")); 312 return Err(CrimError::eos("tag type"));
346 } 313 }
347 314
348 self.parse_tag_params( ctx, &mut tb )?; 315 self.parse_tag_params( ctx, &mut tb )?;
@@ -357,9 +324,9 @@ impl Parser {
357 tb.set_type( TagType::Unary ); 324 tb.set_type( TagType::Unary );
358 } 325 }
359 _ => { 326 _ => {
360 return Err(ParseError::new( 327 return Err(CrimError::new(
361 end_sym.start().clone(), 328 *end_sym.start(),
362 format!("Unexpected symbol {:?} looking for end of tag.", end_sym.symbol()).as_str() 329 format!("Unexpected symbol {:?} looking for end of tag.", end_sym.symbol())
363 )); 330 ));
364 } 331 }
365 } 332 }
@@ -370,31 +337,31 @@ impl Parser {
370 Ok(tb) 337 Ok(tb)
371 } 338 }
372 339
373 fn parse_end_tag<'a>(&self, ctx: &mut Context<'a> ) -> ParseResult<Symbol<'a>> { 340 fn parse_end_tag<'a>(&self, ctx: &mut Context<'a> ) -> CrimResult<Symbol<'a>> {
374 if !ctx.cur().is("end tag",|s| *s == SymbolType::StartPoint )? { 341 if !ctx.cur().is("end tag",|s| *s == SymbolType::StartPoint )? {
375 return Err(ParseError{ 342 return Err(CrimError::new(
376 position: *ctx.cur().unwrap().start(), 343 *ctx.cur().unwrap().start(),
377 what: "Invalid end tag?".to_string(), 344 "Invalid end tag?".to_string()
378 }); 345 ));
379 } 346 }
380 if !ctx.next().is_valid_tag_name()? { 347 if !ctx.next().is_valid_tag_name()? {
381 return Err(ParseError{ 348 return Err(CrimError::new(
382 position: *ctx.cur().unwrap().start(), 349 *ctx.cur().unwrap().start(),
383 what: "Invalid tag name".to_string(), 350 "Invalid tag name".to_string()
384 }); 351 ));
385 } 352 }
386 let name = ctx.cur().unwrap(); 353 let name = ctx.cur().unwrap();
387 if !ctx.next().is("end of end tag", |s| *s == SymbolType::EndFlat )? { 354 if !ctx.next().is("end of end tag", |s| *s == SymbolType::EndFlat )? {
388 return Err(ParseError{ 355 return Err(CrimError::new(
389 position: *ctx.cur().unwrap().start(), 356 *ctx.cur().unwrap().start(),
390 what: "Tag should be <| |] style end tag.".to_string(), 357 "Tag should be <| |] style end tag.".to_string(),
391 }); 358 ));
392 } 359 }
393 ctx.next(); 360 ctx.next();
394 Ok(name) 361 Ok(name)
395 } 362 }
396 363
397 fn parse_tag_body<'a>(&self, ctx: &mut Context<'a> ) -> ParseResult<TagBuilder<'a>> { 364 fn parse_tag_body<'a>(&self, ctx: &mut Context<'a> ) -> CrimResult<TagBuilder<'a>> {
398 let mut tb = self.parse_open_tag( ctx )?; 365 let mut tb = self.parse_open_tag( ctx )?;
399 if tb.is_unary() { 366 if tb.is_unary() {
400 return Ok(tb); 367 return Ok(tb);
@@ -402,7 +369,7 @@ impl Parser {
402 369
403 loop { 370 loop {
404 if ctx.cur().is_none() { 371 if ctx.cur().is_none() {
405 return Err(ParseError::eos(format!("close tag for {:?}", tb.name()).as_str())); 372 return Err(CrimError::eos(format!("close tag for {:?}", tb.name()).as_str()));
406 } 373 }
407 match ctx.cur().unwrap().symbol() { 374 match ctx.cur().unwrap().symbol() {
408 SymbolType::Text(s) => { 375 SymbolType::Text(s) => {
@@ -419,29 +386,29 @@ impl Parser {
419 return Ok(tb); 386 return Ok(tb);
420 } else { 387 } else {
421 // They don't match, complain. 388 // They don't match, complain.
422 return Err(ParseError{ 389 return Err(CrimError::new(
423 position: *end.start(), 390 *end.start(),
424 what: "Mismatched open and closing tags.".to_string() 391 "Mismatched open and closing tags.".to_string()
425 }); 392 ));
426 } 393 }
427 } 394 }
428 SymbolType::Error{..} => { 395 SymbolType::Error{..} => {
429 return self.lex_error( &ctx.cur().unwrap() ); 396 return self.lex_error( &ctx.cur().unwrap() );
430 } 397 }
431 _ => { 398 _ => {
432 return Err(ParseError{ 399 return Err(CrimError::new(
433 position: ctx.cur().unwrap().start().clone(), 400 *ctx.cur().unwrap().start(),
434 what: format!("Unexpected token: {:?}", ctx.cur().unwrap().symbol()), 401 format!("Unexpected token: {:?}", ctx.cur().unwrap().symbol()),
435 }); 402 ));
436 } 403 }
437 } 404 }
438 } 405 }
439 } 406 }
440 407
441 fn parse_tag_params(&self, ctx: &mut Context, tb: &mut TagBuilder ) -> ParseResult<()> { 408 fn parse_tag_params(&self, ctx: &mut Context, tb: &mut TagBuilder ) -> CrimResult<()> {
442 loop { 409 loop {
443 if ctx.cur().is_none() { 410 if ctx.cur().is_none() {
444 return Err(ParseError::eos("tag parameters")); 411 return Err(CrimError::eos("tag parameters"));
445 } 412 }
446 match ctx.cur().unwrap().symbol() { 413 match ctx.cur().unwrap().symbol() {
447 SymbolType::Literal(s) => { 414 SymbolType::Literal(s) => {
@@ -462,7 +429,7 @@ impl Parser {
462 Ok(()) 429 Ok(())
463 } 430 }
464 431
465 fn parse_identifier(&self, ctx: &mut Context ) -> ParseResult<ParamValue> { 432 fn parse_identifier(&self, ctx: &mut Context ) -> CrimResult<ParamValue> {
466 let mut id = Identifier::new(); 433 let mut id = Identifier::new();
467 434
468 loop { 435 loop {
@@ -471,7 +438,7 @@ impl Parser {
471 id.push( IdentifierValue::Name(s.to_string()) ); 438 id.push( IdentifierValue::Name(s.to_string()) );
472 } 439 }
473 } else { 440 } else {
474 return Err(ParseError::new( ctx.cur().unwrap().start().clone(), &format!("Expeceted identifier, found {:?}", ctx.cur().unwrap().symbol() ) ) ); 441 return Err(CrimError::new( ctx.cur().unwrap().start().clone(), format!("Expeceted identifier, found {:?}", ctx.cur().unwrap().symbol() ) ) );
475 } 442 }
476 443
477 if !ctx.next().is("identifier seperator",|s| *s == SymbolType::Period )? { 444 if !ctx.next().is("identifier seperator",|s| *s == SymbolType::Period )? {
@@ -483,10 +450,10 @@ impl Parser {
483 Ok(ParamValue::Identifier(id)) 450 Ok(ParamValue::Identifier(id))
484 } 451 }
485 452
486 fn parse_tag_props(&self, ctx: &mut Context, tb: &mut TagBuilder ) -> ParseResult<()> { 453 fn parse_tag_props(&self, ctx: &mut Context, tb: &mut TagBuilder ) -> CrimResult<()> {
487 loop { 454 loop {
488 if ctx.cur().is_none() { 455 if ctx.cur().is_none() {
489 return Err(ParseError::eos("tag properties")); 456 return Err(CrimError::eos("tag properties"));
490 } 457 }
491 if let SymbolType::Token(s) = ctx.cur().unwrap().symbol() { 458 if let SymbolType::Token(s) = ctx.cur().unwrap().symbol() {
492 if ctx.peek().is_some_and(|s|s.check_type(|t| matches!(t,SymbolType::Equals))) { 459 if ctx.peek().is_some_and(|s|s.check_type(|t| matches!(t,SymbolType::Equals))) {
@@ -495,7 +462,7 @@ impl Parser {
495 let SymbolType::Literal(lv) = sym.symbol() { 462 let SymbolType::Literal(lv) = sym.symbol() {
496 tb.add_prop( s.to_string(), lv.to_string() ); 463 tb.add_prop( s.to_string(), lv.to_string() );
497 } else { 464 } else {
498 return Err(ParseError{position: Position::new(0,0), what: "Expected quoted literal string".to_string()}); 465 return Err(CrimError::new(Position::none(),"Expected quoted literal string".to_string()));
499 } 466 }
500 } else { 467 } else {
501 break; 468 break;
@@ -607,13 +574,13 @@ impl<'a> TagBuilder<'a> {
607 self.tag_type 574 self.tag_type
608 } 575 }
609 576
610 pub fn build_view(mut self, ctx: &Context, outputs: Vec<Output>) -> ParseResult<View> { 577 pub fn build_view(mut self, ctx: &Context, outputs: Vec<Output>) -> CrimResult<View> {
611 if let Some(sym) = self.name { 578 if let Some(sym) = self.name {
612 if *sym.symbol() == SymbolType::View { 579 if *sym.symbol() == SymbolType::View {
613 let name = if let ParamValue::Literal(s) = self.params.swap_remove(0) { 580 let name = if let ParamValue::Literal(s) = self.params.swap_remove(0) {
614 s.to_string() 581 s.to_string()
615 } else { 582 } else {
616 return Err(ParseError::new(Position::none(), "Expected string literal for view name.")); 583 return Err(CrimError::new(Position::none(), "Expected string literal for view name.".to_string()));
617 }; 584 };
618 Ok(View { 585 Ok(View {
619 name: name, 586 name: name,
@@ -623,41 +590,41 @@ impl<'a> TagBuilder<'a> {
623 layout: self.props.get("layout").cloned(), 590 layout: self.props.get("layout").cloned(),
624 }) 591 })
625 } else { 592 } else {
626 Err(ParseError::new(self.start_pos, &format!("Expected tag type view, found {:?}", sym.symbol()))) 593 Err(CrimError::new(self.start_pos, format!("Expected tag type view, found {:?}", sym.symbol())))
627 } 594 }
628 } else { 595 } else {
629 Err(ParseError::new(self.start_pos, "Broken Parser? No tag type found when building view.")) 596 Err(CrimError::new(self.start_pos, "Broken Parser? No tag type found when building view.".to_string()))
630 } 597 }
631 } 598 }
632 599
633 pub fn build_output(mut self) -> ParseResult<Output> { 600 pub fn build_output(mut self) -> CrimResult<Output> {
634 if let Some(sym) = self.name { 601 if let Some(sym) = self.name {
635 if *sym.symbol() == SymbolType::Output { 602 if *sym.symbol() == SymbolType::Output {
636 let name = if let ParamValue::Literal(s) = self.params.swap_remove(0) { 603 let name = if let ParamValue::Literal(s) = self.params.swap_remove(0) {
637 s.to_string() 604 s.to_string()
638 } else { 605 } else {
639 return Err(ParseError::new(Position::none(), "Expected string literal for output name.")); 606 return Err(CrimError::new(Position::none(), "Expected string literal for output name.".into()));
640 }; 607 };
641 Ok(Output { 608 Ok(Output {
642 name: name, 609 name: name,
643 code: self.children, 610 code: self.children,
644 }) 611 })
645 } else { 612 } else {
646 Err(ParseError::new(self.start_pos, &format!("Expected tag type view, found {:?}", sym.symbol()))) 613 Err(CrimError::new(self.start_pos, format!("Expected tag type view, found {:?}", sym.symbol())))
647 } 614 }
648 } else { 615 } else {
649 Err(ParseError::new(self.start_pos, "Broken Parser? No tag type found when building view.")) 616 Err(CrimError::new(self.start_pos, "Broken Parser? No tag type found when building view.".into()))
650 } 617 }
651 } 618 }
652 619
653 pub fn build(mut self) -> ParseResult<Token> { 620 pub fn build(mut self) -> CrimResult<Token> {
654 if let Some(sym) = self.name { 621 if let Some(sym) = self.name {
655 match sym.symbol() { 622 match sym.symbol() {
656 SymbolType::Loop => { 623 SymbolType::Loop => {
657 let id = if let ParamValue::Identifier(id) = self.params.swap_remove(0) { 624 let id = if let ParamValue::Identifier(id) = self.params.swap_remove(0) {
658 id 625 id
659 } else { 626 } else {
660 return Err(ParseError::new(Position::none(), "Identifier for loop variable name.")); 627 return Err(CrimError::new(Position::none(), "Identifier for loop variable name.".into()));
661 }; 628 };
662 Ok(Token::Loop(id, self.children)) 629 Ok(Token::Loop(id, self.children))
663 } 630 }
@@ -665,22 +632,16 @@ impl<'a> TagBuilder<'a> {
665 let id = if let ParamValue::Identifier(id) = self.params.swap_remove(0) { 632 let id = if let ParamValue::Identifier(id) = self.params.swap_remove(0) {
666 id 633 id
667 } else { 634 } else {
668 return Err(ParseError::new(Position::none(), "Identifier for show variable name.")); 635 return Err(CrimError::new(Position::none(), "Identifier for show variable name.".into()));
669 }; 636 };
670 Ok(Token::Show(id, self.props)) 637 Ok(Token::Show(id, self.props))
671 } 638 }
672 _ => { 639 _ => {
673 Err(ParseError { 640 Err(CrimError::new( self.start_pos, "Bad tag type".into()))
674 position: self.start_pos,
675 what: "Bad tag type".to_string(),
676 })
677 } 641 }
678 } 642 }
679 } else { 643 } else {
680 Err(ParseError { 644 Err(CrimError::new(self.start_pos, "Bad tag type".into()))
681 position: self.start_pos,
682 what: "Bad tag type".to_string(),
683 })
684 } 645 }
685 } 646 }
686} 647}