-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfield.rs
More file actions
45 lines (41 loc) · 1.51 KB
/
field.rs
File metadata and controls
45 lines (41 loc) · 1.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
use rusty_common::*;
use rusty_pc::*;
use crate::expr::expr_ws_keyword_p;
use crate::expr::file_handle::file_handle_p;
use crate::input::StringView;
use crate::pc_specific::*;
use crate::tokens::comma_ws;
use crate::{BuiltInSub, ParserError, *};
/// Example: FIELD #1, 10 AS FirstName$, 20 AS LastName$
pub fn parse() -> impl Parser<StringView, Output = Statement, Error = ParserError> {
seq4(
keyword_ws_p(Keyword::Field),
file_handle_p().or_expected("file-number"),
comma_ws(),
csv_non_opt(field_item_p(), "field width"),
|_, file_number, _, fields| {
Statement::built_in_sub_call(BuiltInSub::Field, build_args(file_number, fields))
},
)
}
fn field_item_p() -> impl Parser<StringView, Output = (ExpressionPos, NamePos), Error = ParserError>
{
expr_ws_keyword_p(Keyword::As).and_tuple(demand_lead_ws(
name_p().with_pos().or_expected("variable name"),
))
}
fn build_args(
file_number_pos: Positioned<FileHandle>,
fields: Vec<(ExpressionPos, NamePos)>,
) -> Expressions {
let mut args: Expressions = vec![];
args.push(file_number_pos.map(Expression::from));
for (width, Positioned { element: name, pos }) in fields {
args.push(width);
let variable_name: String = name.as_bare_name().to_string();
args.push(Expression::StringLiteral(variable_name).at_pos(pos));
// to lint the variable, not used at runtime
args.push(Expression::Variable(name, VariableInfo::unresolved()).at_pos(pos));
}
args
}