summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/context.rs124
-rw-r--r--src/error.rs13
-rw-r--r--src/lib.rs110
-rw-r--r--src/parser.rs60
4 files changed, 199 insertions, 108 deletions
diff --git a/src/context.rs b/src/context.rs
new file mode 100644
index 0000000..78a7940
--- /dev/null
+++ b/src/context.rs
@@ -0,0 +1,124 @@
1use std::collections::HashMap;
2
3use crate::{Identifier,IdentifierValue};
4
5pub type Context = HashMap<String,Value>;
6
7pub trait MappedStructure {
8 fn get_value(&self, id: &Identifier) -> Option<Value>;
9}
10
11impl MappedStructure for Context {
12 fn get_value(&self, id: &Identifier) -> Option<Value> {
13 if id.len() == 0 {
14 return None;
15 }
16 let mut cur_val : Option<&Value> = if let IdentifierValue::Name(s) = &id[0] {
17 self.get(s)
18 } else {
19 return None;
20 };
21 if cur_val.is_none() {
22 return None;
23 }
24
25 for idx in 1..id.len() {
26 if let IdentifierValue::Name(s) = &id[idx] &&
27 let Some(Value::Dictionary(d)) = &cur_val {
28 cur_val.replace( if let Some(v) = d.get(s) {
29 v
30 } else {
31 return None;
32 });
33 }
34 }
35
36 return cur_val.cloned();
37 }
38}
39
40#[derive(Debug,Clone)]
41pub enum Value {
42 Dictionary(Context),
43 List(Vec<Value>),
44 String(String),
45 Int(i64),
46 Float(f64),
47 Identifier(Identifier),
48}
49
50impl From<&str> for Value {
51 fn from(val: &str ) -> Value {
52 Value::String(val.into())
53 }
54}
55
56impl From<String> for Value {
57 fn from(val: String) -> Value {
58 Value::String(val)
59 }
60}
61
62impl From<i64> for Value {
63 fn from(val: i64) -> Value {
64 Value::Int(val)
65 }
66}
67
68impl From<f64> for Value {
69 fn from(val: f64) -> Value {
70 Value::Float(val)
71 }
72}
73
74impl From<Vec<Value>> for Value {
75 fn from(val: Vec<Value>) -> Value {
76 Value::List(val)
77 }
78}
79
80impl From<&[Value]> for Value {
81 fn from(val: &[Value]) -> Value {
82 Value::List(Vec::from(val))
83 }
84}
85
86impl From<Context> for Value {
87 fn from(val: Context) -> Value {
88 Value::Dictionary(val)
89 }
90}
91
92impl<const N: usize> From<[(String,Value); N]> for Value {
93 fn from(val: [(String,Value); N]) -> Value {
94 Value::Dictionary(HashMap::from(val))
95 }
96}
97
98/*
99impl MappedStructure for Value {
100 fn get_value(&self, id: &Identifier) -> Option<Value> {
101 if id.len() == 0 {
102 return Some(self);
103 }
104 match Value {
105 Value::Dictionary(dict) => {
106 }
107 }
108 let mut cur_val : Option<&Value> = Some(&self);
109
110 for idx in 0..id.len() {
111 if let IdentifierValue::Name(s) = &id[idx] &&
112 let Some(Value::Dictionary(d)) = &cur_val {
113 cur_val.replace( if let Some(v) = d.get(s) {
114 v
115 } else {
116 return None;
117 });
118 }
119 }
120
121 return cur_val.cloned();
122 }
123}
124*/
diff --git a/src/error.rs b/src/error.rs
index a2b6d96..a2349ee 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -11,15 +11,22 @@ pub struct CrimError {
11} 11}
12 12
13impl CrimError { 13impl CrimError {
14 pub fn new( position: Position, what: String ) -> Self { 14 pub fn parse( position: Position, what: String ) -> Self {
15 CrimError { 15 Self {
16 position, 16 position,
17 what, 17 what,
18 } 18 }
19 } 19 }
20 20
21 pub fn other(what: String) -> Self {
22 Self {
23 position: Position::none(),
24 what,
25 }
26 }
27
21 pub fn eos( context: &str ) -> Self { 28 pub fn eos( context: &str ) -> Self {
22 CrimError { 29 Self {
23 position: Position::none(), 30 position: Position::none(),
24 what: format!("Premature end of stream while looking for {}", context), 31 what: format!("Premature end of stream while looking for {}", context),
25 } 32 }
diff --git a/src/lib.rs b/src/lib.rs
index 9b838f3..b0bc688 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -7,9 +7,11 @@ mod lexer;
7mod parser; 7mod parser;
8mod position; 8mod position;
9mod error; 9mod error;
10mod context;
10 11
11pub use error::{CrimError,CrimResult}; 12pub use error::{CrimError,CrimResult};
12pub use position::*; 13pub use position::*;
14pub use context::{Context,Value,MappedStructure};
13 15
14#[derive(Debug)] 16#[derive(Debug)]
15pub struct Crimtag { 17pub struct Crimtag {
@@ -39,7 +41,7 @@ struct View {
39} 41}
40 42
41impl View { 43impl View {
42 fn process(&self, input: &impl MappedStructure) -> Result<Context, CrimError> { 44 fn process(&self, input: &impl MappedStructure) -> CrimResult<Context> {
43 let mut out_vars = Context::new(); 45 let mut out_vars = Context::new();
44 for output in &self.outputs { 46 for output in &self.outputs {
45 let mut buf = String::new(); 47 let mut buf = String::new();
@@ -69,56 +71,12 @@ enum Token {
69} 71}
70 72
71#[derive(Debug,Clone)] 73#[derive(Debug,Clone)]
72pub enum Value {
73 Dictionary(Context),
74 List(Vec<Value>),
75 String(String),
76 Int(i64),
77 Float(f64),
78 Identifier(Identifier),
79}
80
81#[derive(Debug,Clone)]
82pub enum IdentifierValue { 74pub enum IdentifierValue {
83 Name(String), 75 Name(String),
84 Index(usize), 76 Index(usize),
85} 77}
86 78
87pub type Identifier = Vec<IdentifierValue>; 79pub type Identifier = Vec<IdentifierValue>;
88pub type Context = HashMap<String,Value>;
89
90pub trait MappedStructure {
91 fn get_value(&self, id: &Identifier) -> Option<Value>;
92}
93
94impl MappedStructure for Context {
95 fn get_value(&self, id: &Identifier) -> Option<Value> {
96 if id.len() == 0 {
97 return None;
98 }
99 let mut cur_val : Option<&Value> = if let IdentifierValue::Name(s) = &id[0] {
100 self.get(s)
101 } else {
102 return None;
103 };
104 if cur_val.is_none() {
105 return None;
106 }
107
108 for idx in 1..id.len() {
109 if let IdentifierValue::Name(s) = &id[idx] &&
110 let Some(Value::Dictionary(d)) = &cur_val {
111 cur_val.replace( if let Some(v) = d.get(s) {
112 v
113 } else {
114 return None;
115 });
116 }
117 }
118
119 return cur_val.cloned();
120 }
121}
122 80
123impl Crimtag { 81impl Crimtag {
124 pub fn new() -> Self { 82 pub fn new() -> Self {
@@ -169,13 +127,13 @@ impl Crimtag {
169 Ok(()) 127 Ok(())
170 } 128 }
171 129
172 pub fn load_static(&mut self, data: &str) -> Result<(),CrimError> { 130 pub fn load_static(&mut self, data: &str) -> CrimResult<()> {
173 let source_id = self.id_source( &ViewSource::Static ); 131 let source_id = self.id_source( &ViewSource::Static );
174 let p = parser::Parser::new(); 132 let p = parser::Parser::new();
175 self.register_views( p.parse( &data, source_id )? ) 133 self.register_views( p.parse( &data, source_id )? )
176 } 134 }
177 135
178 pub fn load_external(&mut self, key: &str, data: &str) -> Result<(),CrimError> { 136 pub fn load_external(&mut self, key: &str, data: &str) -> CrimResult<()> {
179 let source_id = self.id_source( 137 let source_id = self.id_source(
180 &ViewSource::External{ key: key.to_string()} 138 &ViewSource::External{ key: key.to_string()}
181 ); 139 );
@@ -186,7 +144,7 @@ impl Crimtag {
186 ) 144 )
187 } 145 }
188 146
189 fn register_views(&mut self, views: Vec<View>) -> Result<(),CrimError> { 147 fn register_views(&mut self, views: Vec<View>) -> CrimResult<()> {
190 for view in views { 148 for view in views {
191 self.views.insert( view.name.clone(), view ); 149 self.views.insert( view.name.clone(), view );
192 } 150 }
@@ -205,15 +163,15 @@ impl Crimtag {
205 } 163 }
206 } 164 }
207 165
208 pub fn render_partial(&self, view: &str, input: &impl MappedStructure ) -> Result<Context,CrimError> { 166 pub fn render_partial(&self, view: &str, input: &impl MappedStructure ) -> CrimResult<Context> {
209 if let Some(view) = self.views.get(view) { 167 if let Some(view) = self.views.get(view) {
210 return view.process( input ) 168 return view.process( input )
211 } else { 169 } else {
212 return Err(CrimError::new(Position::none(),"No such view found".into())); 170 return Err(CrimError::other("No such view found".into()));
213 } 171 }
214 } 172 }
215 173
216 pub fn render(&self, view: &str, input: &impl MappedStructure ) -> Result<String,CrimError> { 174 pub fn render(&self, view: &str, input: &impl MappedStructure ) -> CrimResult<String> {
217 if let Some(view) = self.views.get( view ) { 175 if let Some(view) = self.views.get( view ) {
218 let mut output = view.process( input )?; 176 let mut output = view.process( input )?;
219 if let Some(l) = &view.layout { 177 if let Some(l) = &view.layout {
@@ -224,17 +182,17 @@ impl Crimtag {
224 182
225 Ok(s) 183 Ok(s)
226 } else { 184 } else {
227 Err(CrimError::new(Position::none(), "No content found in root layout.".into())) 185 Err(CrimError::other("No content found in root layout.".into()))
228 } 186 }
229 } 187 }
230 188
231 } else { 189 } else {
232 Err(CrimError::new(Position::none(),"No such view found".into())) 190 Err(CrimError::other("No such view found".into()))
233 } 191 }
234 } 192 }
235} 193}
236 194
237fn exec(input: &impl MappedStructure, tokens: &Vec<Token>, buf: &mut String) -> Result<(),CrimError> { 195fn exec(input: &impl MappedStructure, tokens: &Vec<Token>, buf: &mut String) -> CrimResult<()> {
238 for token in tokens { 196 for token in tokens {
239 match token { 197 match token {
240 Token::Loop(ident,code) => { 198 Token::Loop(ident,code) => {
@@ -363,28 +321,28 @@ Now with explicit outputs:
363 } 321 }
364 322
365 let ctx = Context::from([ 323 let ctx = Context::from([
366 ("people".to_string(), crate::Value::List(vec![ 324 ("people".to_string(), vec![
367 crate::Value::Dictionary(Context::from([ 325 [
368 ("first_name".to_string(), Value::String("Joe".to_string())), 326 ("first_name".into(), "Joe".into()),
369 ("last_name".to_string(), Value::String("Smith".to_string())), 327 ("last_name".into(), "Smith".into()),
370 ("title".to_string(), Value::String("CEO".to_string())), 328 ("title".into(), "CEO".into()),
371 ])), 329 ].into(),
372 crate::Value::Dictionary(Context::from([ 330 [
373 ("first_name".to_string(), Value::String("Chris".to_string())), 331 ("first_name".into(), "Chris".into()),
374 ("last_name".to_string(), Value::String("Perkens".to_string())), 332 ("last_name".into(), "Perkens".into()),
375 ("title".to_string(), Value::String("Baconeer".to_string())), 333 ("title".into(), "Baconeer".into()),
376 ])), 334 ].into(),
377 crate::Value::Dictionary(Context::from([ 335 [
378 ("first_name".to_string(), Value::String("Will".to_string())), 336 ("first_name".into(), "Will".into()),
379 ("last_name".to_string(), Value::String("Power".to_string())), 337 ("last_name".into(), "Power".into()),
380 ("title".to_string(), Value::String("CFO".to_string())), 338 ("title".into(), "CFO".into()),
381 ])), 339 ].into(),
382 crate::Value::Dictionary(Context::from([ 340 [
383 ("first_name".to_string(), Value::String("Justin".to_string())), 341 ("first_name".into(), "Justin".into()),
384 ("last_name".to_string(), Value::String("Time".to_string())), 342 ("last_name".into(), "Time".into()),
385 ("title".to_string(), Value::String("CIO".to_string())), 343 ("title".into(), "CIO".into()),
386 ])), 344 ].into(),
387 ])), 345 ].into()),
388 ]); 346 ]);
389 match ct.render("index", &ctx) { 347 match ct.render("index", &ctx) {
390 Ok(s) => println!("View result: {}", s ), 348 Ok(s) => println!("View result: {}", s ),
diff --git a/src/parser.rs b/src/parser.rs
index 83144fb..be5492c 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -76,7 +76,7 @@ impl<'a> SymbolHelper for Option<Symbol<'a>> {
76 _ => false 76 _ => false
77 }) 77 })
78 } else { 78 } else {
79 Err(CrimError::new( 79 Err(CrimError::parse(
80 Position::none(), 80 Position::none(),
81 "Unexpeceted end of stream.".to_string() 81 "Unexpeceted end of stream.".to_string()
82 )) 82 ))
@@ -172,11 +172,11 @@ impl Parser {
172 172
173 fn lex_error<T>(&self, error: &Symbol) -> CrimResult<T> { 173 fn lex_error<T>(&self, error: &Symbol) -> CrimResult<T> {
174 if let SymbolType::Error{what} = error.symbol() { 174 if let SymbolType::Error{what} = error.symbol() {
175 Err(CrimError::new( *error.start(), 175 Err(CrimError::parse( *error.start(),
176 format!("What: {:?}", *what) 176 format!("What: {:?}", *what)
177 )) 177 ))
178 } else { 178 } else {
179 Err(CrimError::new( Position::none(), "Not an error?".into())) 179 Err(CrimError::parse( Position::none(), "Not an error?".into()))
180 } 180 }
181 } 181 }
182 182
@@ -214,7 +214,7 @@ impl Parser {
214 fn parse_tag_view(&self, ctx: &mut Context) -> CrimResult<View> { 214 fn parse_tag_view(&self, ctx: &mut Context) -> CrimResult<View> {
215 let tb = self.parse_open_tag( ctx )?; 215 let tb = self.parse_open_tag( ctx )?;
216 if !tb.is_name( &SymbolType::View ) { 216 if !tb.is_name( &SymbolType::View ) {
217 return Err(CrimError::new(tb.start_pos(), 217 return Err(CrimError::parse(tb.start_pos(),
218 "Unexpected tag type, only frament allowed at root".into() 218 "Unexpected tag type, only frament allowed at root".into()
219 )); 219 ));
220 } 220 }
@@ -260,7 +260,7 @@ impl Parser {
260 }); 260 });
261 } else { 261 } else {
262 if !all_text { 262 if !all_text {
263 return Err(CrimError::new( 263 return Err(CrimError::parse(
264 *end.start(), 264 *end.start(),
265 "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()
266 )); 266 ));
@@ -269,7 +269,7 @@ impl Parser {
269 return tb.build_view(ctx,outputs); 269 return tb.build_view(ctx,outputs);
270 } else { 270 } else {
271 // They don't match, complain. 271 // They don't match, complain.
272 return Err(CrimError::new( 272 return Err(CrimError::parse(
273 *end.start(), 273 *end.start(),
274 "Mismatched open and closing tags.".to_string() 274 "Mismatched open and closing tags.".to_string()
275 )); 275 ));
@@ -279,7 +279,7 @@ impl Parser {
279 return self.lex_error( &ctx.cur().unwrap() ); 279 return self.lex_error( &ctx.cur().unwrap() );
280 } 280 }
281 _ => { 281 _ => {
282 return Err(CrimError::new( 282 return Err(CrimError::parse(
283 *ctx.cur().unwrap().start(), 283 *ctx.cur().unwrap().start(),
284 format!("Unexpected tag in view root: {:?}", ctx.cur().unwrap().symbol()) 284 format!("Unexpected tag in view root: {:?}", ctx.cur().unwrap().symbol())
285 )); 285 ));
@@ -302,7 +302,7 @@ impl Parser {
302 tb.set_name( name_sym ); 302 tb.set_name( name_sym );
303 } 303 }
304 _ => { 304 _ => {
305 return Err(CrimError::new( 305 return Err(CrimError::parse(
306 *ctx.cur().unwrap().start(), 306 *ctx.cur().unwrap().start(),
307 "Unexpected symbol".to_string() 307 "Unexpected symbol".to_string()
308 )); 308 ));
@@ -318,13 +318,13 @@ impl Parser {
318 if let Some(end_sym) = ctx.cur() { 318 if let Some(end_sym) = ctx.cur() {
319 match end_sym.symbol() { 319 match end_sym.symbol() {
320 SymbolType::EndPoint => { 320 SymbolType::EndPoint => {
321 tb.set_type( TagType::BinaryOpen ); 321 tb.set_type( TagType::MultinaryOpen );
322 } 322 }
323 SymbolType::EndFlat => { 323 SymbolType::EndFlat => {
324 tb.set_type( TagType::Unary ); 324 tb.set_type( TagType::Unary );
325 } 325 }
326 _ => { 326 _ => {
327 return Err(CrimError::new( 327 return Err(CrimError::parse(
328 *end_sym.start(), 328 *end_sym.start(),
329 format!("Unexpected symbol {:?} looking for end of tag.", end_sym.symbol()) 329 format!("Unexpected symbol {:?} looking for end of tag.", end_sym.symbol())
330 )); 330 ));
@@ -339,20 +339,20 @@ impl Parser {
339 339
340 fn parse_end_tag<'a>(&self, ctx: &mut Context<'a> ) -> CrimResult<Symbol<'a>> { 340 fn parse_end_tag<'a>(&self, ctx: &mut Context<'a> ) -> CrimResult<Symbol<'a>> {
341 if !ctx.cur().is("end tag",|s| *s == SymbolType::StartPoint )? { 341 if !ctx.cur().is("end tag",|s| *s == SymbolType::StartPoint )? {
342 return Err(CrimError::new( 342 return Err(CrimError::parse(
343 *ctx.cur().unwrap().start(), 343 *ctx.cur().unwrap().start(),
344 "Invalid end tag?".to_string() 344 "Invalid end tag?".to_string()
345 )); 345 ));
346 } 346 }
347 if !ctx.next().is_valid_tag_name()? { 347 if !ctx.next().is_valid_tag_name()? {
348 return Err(CrimError::new( 348 return Err(CrimError::parse(
349 *ctx.cur().unwrap().start(), 349 *ctx.cur().unwrap().start(),
350 "Invalid tag name".to_string() 350 "Invalid tag name".to_string()
351 )); 351 ));
352 } 352 }
353 let name = ctx.cur().unwrap(); 353 let name = ctx.cur().unwrap();
354 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 )? {
355 return Err(CrimError::new( 355 return Err(CrimError::parse(
356 *ctx.cur().unwrap().start(), 356 *ctx.cur().unwrap().start(),
357 "Tag should be <| |] style end tag.".to_string(), 357 "Tag should be <| |] style end tag.".to_string(),
358 )); 358 ));
@@ -386,7 +386,7 @@ impl Parser {
386 return Ok(tb); 386 return Ok(tb);
387 } else { 387 } else {
388 // They don't match, complain. 388 // They don't match, complain.
389 return Err(CrimError::new( 389 return Err(CrimError::parse(
390 *end.start(), 390 *end.start(),
391 "Mismatched open and closing tags.".to_string() 391 "Mismatched open and closing tags.".to_string()
392 )); 392 ));
@@ -396,7 +396,7 @@ impl Parser {
396 return self.lex_error( &ctx.cur().unwrap() ); 396 return self.lex_error( &ctx.cur().unwrap() );
397 } 397 }
398 _ => { 398 _ => {
399 return Err(CrimError::new( 399 return Err(CrimError::parse(
400 *ctx.cur().unwrap().start(), 400 *ctx.cur().unwrap().start(),
401 format!("Unexpected token: {:?}", ctx.cur().unwrap().symbol()), 401 format!("Unexpected token: {:?}", ctx.cur().unwrap().symbol()),
402 )); 402 ));
@@ -438,7 +438,7 @@ impl Parser {
438 id.push( IdentifierValue::Name(s.to_string()) ); 438 id.push( IdentifierValue::Name(s.to_string()) );
439 } 439 }
440 } else { 440 } else {
441 return Err(CrimError::new( ctx.cur().unwrap().start().clone(), format!("Expeceted identifier, found {:?}", ctx.cur().unwrap().symbol() ) ) ); 441 return Err(CrimError::parse( ctx.cur().unwrap().start().clone(), format!("Expeceted identifier, found {:?}", ctx.cur().unwrap().symbol() ) ) );
442 } 442 }
443 443
444 if !ctx.next().is("identifier seperator",|s| *s == SymbolType::Period )? { 444 if !ctx.next().is("identifier seperator",|s| *s == SymbolType::Period )? {
@@ -462,7 +462,7 @@ impl Parser {
462 let SymbolType::Literal(lv) = sym.symbol() { 462 let SymbolType::Literal(lv) = sym.symbol() {
463 tb.add_prop( s.to_string(), lv.to_string() ); 463 tb.add_prop( s.to_string(), lv.to_string() );
464 } else { 464 } else {
465 return Err(CrimError::new(Position::none(),"Expected quoted literal string".to_string())); 465 return Err(CrimError::parse(Position::none(),"Expected quoted literal string".to_string()));
466 } 466 }
467 } else { 467 } else {
468 break; 468 break;
@@ -480,7 +480,8 @@ impl Parser {
480enum TagType { 480enum TagType {
481 Unknown, 481 Unknown,
482 Unary, 482 Unary,
483 BinaryOpen, 483 MultinaryOpen,
484 MultinaryMid,
484} 485}
485 486
486struct TagBuilder<'a> { 487struct TagBuilder<'a> {
@@ -523,7 +524,8 @@ impl<'a> TagBuilder<'a> {
523 } 524 }
524 525
525 pub fn can_have_children(&self) -> bool { 526 pub fn can_have_children(&self) -> bool {
526 if self.tag_type == TagType::BinaryOpen { 527 if self.tag_type == TagType::MultinaryOpen ||
528 self.tag_type == TagType::MultinaryMid {
527 true 529 true
528 } else { 530 } else {
529 false 531 false
@@ -580,7 +582,7 @@ impl<'a> TagBuilder<'a> {
580 let name = if let ParamValue::Literal(s) = self.params.swap_remove(0) { 582 let name = if let ParamValue::Literal(s) = self.params.swap_remove(0) {
581 s.to_string() 583 s.to_string()
582 } else { 584 } else {
583 return Err(CrimError::new(Position::none(), "Expected string literal for view name.".to_string())); 585 return Err(CrimError::parse(Position::none(), "Expected string literal for view name.".to_string()));
584 }; 586 };
585 Ok(View { 587 Ok(View {
586 name: name, 588 name: name,
@@ -590,10 +592,10 @@ impl<'a> TagBuilder<'a> {
590 layout: self.props.get("layout").cloned(), 592 layout: self.props.get("layout").cloned(),
591 }) 593 })
592 } else { 594 } else {
593 Err(CrimError::new(self.start_pos, format!("Expected tag type view, found {:?}", sym.symbol()))) 595 Err(CrimError::parse(self.start_pos, format!("Expected tag type view, found {:?}", sym.symbol())))
594 } 596 }
595 } else { 597 } else {
596 Err(CrimError::new(self.start_pos, "Broken Parser? No tag type found when building view.".to_string())) 598 Err(CrimError::parse(self.start_pos, "Broken Parser? No tag type found when building view.".to_string()))
597 } 599 }
598 } 600 }
599 601
@@ -603,17 +605,17 @@ impl<'a> TagBuilder<'a> {
603 let name = if let ParamValue::Literal(s) = self.params.swap_remove(0) { 605 let name = if let ParamValue::Literal(s) = self.params.swap_remove(0) {
604 s.to_string() 606 s.to_string()
605 } else { 607 } else {
606 return Err(CrimError::new(Position::none(), "Expected string literal for output name.".into())); 608 return Err(CrimError::parse(Position::none(), "Expected string literal for output name.".into()));
607 }; 609 };
608 Ok(Output { 610 Ok(Output {
609 name: name, 611 name: name,
610 code: self.children, 612 code: self.children,
611 }) 613 })
612 } else { 614 } else {
613 Err(CrimError::new(self.start_pos, format!("Expected tag type view, found {:?}", sym.symbol()))) 615 Err(CrimError::parse(self.start_pos, format!("Expected tag type view, found {:?}", sym.symbol())))
614 } 616 }
615 } else { 617 } else {
616 Err(CrimError::new(self.start_pos, "Broken Parser? No tag type found when building view.".into())) 618 Err(CrimError::parse(self.start_pos, "Broken Parser? No tag type found when building view.".into()))
617 } 619 }
618 } 620 }
619 621
@@ -624,7 +626,7 @@ impl<'a> TagBuilder<'a> {
624 let id = if let ParamValue::Identifier(id) = self.params.swap_remove(0) { 626 let id = if let ParamValue::Identifier(id) = self.params.swap_remove(0) {
625 id 627 id
626 } else { 628 } else {
627 return Err(CrimError::new(Position::none(), "Identifier for loop variable name.".into())); 629 return Err(CrimError::parse(Position::none(), "Identifier for loop variable name.".into()));
628 }; 630 };
629 Ok(Token::Loop(id, self.children)) 631 Ok(Token::Loop(id, self.children))
630 } 632 }
@@ -632,16 +634,16 @@ impl<'a> TagBuilder<'a> {
632 let id = if let ParamValue::Identifier(id) = self.params.swap_remove(0) { 634 let id = if let ParamValue::Identifier(id) = self.params.swap_remove(0) {
633 id 635 id
634 } else { 636 } else {
635 return Err(CrimError::new(Position::none(), "Identifier for show variable name.".into())); 637 return Err(CrimError::parse(Position::none(), "Identifier for show variable name.".into()));
636 }; 638 };
637 Ok(Token::Show(id, self.props)) 639 Ok(Token::Show(id, self.props))
638 } 640 }
639 _ => { 641 _ => {
640 Err(CrimError::new( self.start_pos, "Bad tag type".into())) 642 Err(CrimError::parse( self.start_pos, "Bad tag type".into()))
641 } 643 }
642 } 644 }
643 } else { 645 } else {
644 Err(CrimError::new(self.start_pos, "Bad tag type".into())) 646 Err(CrimError::parse(self.start_pos, "Bad tag type".into()))
645 } 647 }
646 } 648 }
647} 649}