xshade_parser/parser/
mod.rs1use nom::types::CompleteStr;
2use nom::{Err, ErrorKind, Context};
3use nom_locate::LocatedSpan;
4use ::ast::*;
5use ::error::*;
6
7mod expressions;
8
9mod ws;
10mod identifier;
11mod structs;
12mod functions;
13mod types;
14
15use self::ws::*;
16pub use self::identifier::*;
17pub use self::structs::*;
18pub use self::functions::*;
19pub use self::types::*;
20pub use self::expressions::*;
21
22pub type NomSpan<'a> = LocatedSpan<CompleteStr<'a>>;
23
24named!(parse_number<NomSpan, NomSpan>,
25 recognize!(
26 do_parse!(
27 many1!(one_of!("0123456789")) >>
28 ()
29 )
30 )
31);
32
33named!(parse_operator<NomSpan, OperatorType>,
34 alt!(
35 do_parse!(char!('+') >> (OperatorType::Plus)) |
36 do_parse!(char!('-') >> (OperatorType::Minus)) |
37 do_parse!(char!('*') >> (OperatorType::Multiply)) |
38 do_parse!(char!('/') >> (OperatorType::Divide))
39 )
40);
41
42named!(parse_local_statement<NomSpan, Statement>,
43 do_parse!(
44 from: ws!(tag!("let")) >>
45 symbol_name: parse_identifier >>
46 ws!(tag!("=")) >>
47 expression: parse_expression >>
48 to: ws!(tag!(";")) >>
49 (Statement::Local(
50 LocalStatement{
51 span: Span::from_to(Span::from_nom_span(&from), Span::from_nom_span(&to)),
52 symbol_name: symbol_name,
53 expression: expression,
54 }
55 ))
56 )
57);
58
59named!(parse_return_statement<NomSpan, Statement>,
60 do_parse!(
61 from: ws!(tag!("return")) >>
62 expression: parse_expression >>
63 to: ws!(tag!(";")) >>
64 (Statement::Return(ReturnStatement{
65 span: Span::from_to(Span::from_nom_span(&from), Span::from_nom_span(&to)),
66 expression: expression,
67 }))
68 )
69);
70
71named!(parse_expression_statement<NomSpan, Statement>,
72 do_parse!(
73 expression: parse_expression >>
74 semicolon: ws!(tag!(";")) >>
75 (Statement::Expression(
76 ExpressionStatement {
77 span: Span::from_to(expression.get_span(), Span::from_nom_span(&semicolon)),
78 expression,
79 }
80 ))
81 )
82);
83
84named!(parse_block_statements<NomSpan, Vec<Statement>>,
85 many0!(
86 ws!(
87 alt!(
88 parse_local_statement |
89 parse_return_statement |
90 parse_expression_statement
91 )
92 )
93 )
94);
95
96named!(parse_block_declaration<NomSpan, BlockDeclaration>,
97 do_parse!(
98 from: ws!(tag!("{")) >>
99 statements: parse_block_statements >>
100 to: ws!(tag!("}")) >>
101 (BlockDeclaration{
102 span: Span::from_to(Span::from_nom_span(&from), Span::from_nom_span(&to)),
103 statements: statements,
104 })
105 )
106);
107
108named!(parse<NomSpan, Ast>,
109 do_parse!(
110 ws0 >>
111 ast: many0!(
112 alt!(
113 parse_struct |
114 parse_function
115 )
116 ) >>
117 ws0 >>
118 return_error!(add_return_error!(ErrorKind::Custom(ParseErrorKind::InvalidTopLevelItem as u32), eof!())) >>
119 (ast)
120 )
121);
122
123pub fn parse_str(program: &str) -> ParseResult<Ast> {
132 let input = NomSpan::new(CompleteStr(program));
133 let output = parse(input);
134
135 match output {
136 Ok((remaining, ast)) => {
137 if remaining.fragment.len() > 0 {
138 unimplemented!("handle remaining")
139 }
140
141 Ok(ast)
142 },
143 Err(Err::Incomplete(_needed)) => {
144 Err(ParseError::new(Span::new(0, 0, 0, 0), ParseErrorKind::MissingError))
145 },
146 Err(Err::Error(error)) | Err(Err::Failure(error)) => {
147 match error {
148 Context::Code(span, ErrorKind::Custom(error_number)) => {
149 return Err(ParseError::new(
150 Span::from_nom_span(&span),
151 ParseErrorKind::from(error_number)
152 ));
153 }
154
155 Context::Code(span, _error_kind) => {
156 println!("{:#?}", _error_kind);
157 return Err(ParseError::new(
158 Span::from_nom_span(&span),
159 ParseErrorKind::MissingError,
160 ));
161 }
162 }
163 },
164 }
165}