mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -04:00
FEATURE: Parse out statements.
This commit is contained in:
parent
30248e7e01
commit
f3e769095d
@ -799,6 +799,9 @@ pub enum Statement {
|
|||||||
|
|
||||||
// Assert statement
|
// Assert statement
|
||||||
Assert(Token),
|
Assert(Token),
|
||||||
|
|
||||||
|
// Identify an Expression for output.
|
||||||
|
Output(Token, Expression),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -293,7 +293,7 @@ pub struct AssertCollector {
|
|||||||
pub failures: String,
|
pub failures: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builder handles building ucg code.
|
/// Builder handles building ucg code for a single file..
|
||||||
pub struct Builder {
|
pub struct Builder {
|
||||||
root: PathBuf,
|
root: PathBuf,
|
||||||
validate_mode: bool,
|
validate_mode: bool,
|
||||||
@ -306,10 +306,12 @@ pub struct Builder {
|
|||||||
assets: ValueMap,
|
assets: ValueMap,
|
||||||
// List of file paths we have already parsed.
|
// List of file paths we have already parsed.
|
||||||
files: HashSet<String>,
|
files: HashSet<String>,
|
||||||
/// out is our built output.
|
/// build_output is our built output.
|
||||||
out: ValueMap,
|
build_output: ValueMap,
|
||||||
/// last is the result of the last statement.
|
/// last is the result of the last statement.
|
||||||
pub last: Option<Rc<Val>>,
|
pub last: Option<Rc<Val>>,
|
||||||
|
// FIXME(jwall): This should be a per file mapping.
|
||||||
|
out_lock: Option<(String, Rc<Val>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! eval_binary_expr {
|
macro_rules! eval_binary_expr {
|
||||||
@ -330,7 +332,7 @@ macro_rules! eval_binary_expr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Builder {
|
impl Builder {
|
||||||
// FIXME(jwall): This needs some unit tests.
|
// TOOD(jwall): This needs some unit tests.
|
||||||
fn tuple_to_val(&self, fields: &Vec<(Token, Expression)>) -> Result<Rc<Val>, Box<Error>> {
|
fn tuple_to_val(&self, fields: &Vec<(Token, Expression)>) -> Result<Rc<Val>, Box<Error>> {
|
||||||
let mut new_fields = Vec::<(Positioned<String>, Rc<Val>)>::new();
|
let mut new_fields = Vec::<(Positioned<String>, Rc<Val>)>::new();
|
||||||
for &(ref name, ref expr) in fields.iter() {
|
for &(ref name, ref expr) in fields.iter() {
|
||||||
@ -403,7 +405,8 @@ impl Builder {
|
|||||||
env: env,
|
env: env,
|
||||||
assets: HashMap::new(),
|
assets: HashMap::new(),
|
||||||
files: HashSet::new(),
|
files: HashSet::new(),
|
||||||
out: scope,
|
build_output: scope,
|
||||||
|
out_lock: None,
|
||||||
last: None,
|
last: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -473,9 +476,10 @@ impl Builder {
|
|||||||
if !self.files.contains(&key) {
|
if !self.files.contains(&key) {
|
||||||
// Only parse the file once on import.
|
// Only parse the file once on import.
|
||||||
if self.assets.get(&positioned_sym).is_none() {
|
if self.assets.get(&positioned_sym).is_none() {
|
||||||
|
// FIXME(jwall): We should be sharing our assets collection.
|
||||||
let mut b = Self::new(normalized);
|
let mut b = Self::new(normalized);
|
||||||
try!(b.build_file(&def.path.fragment));
|
try!(b.build_file(&def.path.fragment));
|
||||||
let fields: Vec<(Positioned<String>, Rc<Val>)> = b.out.drain().collect();
|
let fields: Vec<(Positioned<String>, Rc<Val>)> = b.build_output.drain().collect();
|
||||||
let result = Rc::new(Val::Tuple(fields));
|
let result = Rc::new(Val::Tuple(fields));
|
||||||
self.assets.entry(positioned_sym).or_insert(result.clone());
|
self.assets.entry(positioned_sym).or_insert(result.clone());
|
||||||
self.files.insert(def.path.fragment.clone());
|
self.files.insert(def.path.fragment.clone());
|
||||||
@ -504,7 +508,7 @@ impl Builder {
|
|||||||
fn build_let(&mut self, def: &LetDef) -> Result<Rc<Val>, Box<Error>> {
|
fn build_let(&mut self, def: &LetDef) -> Result<Rc<Val>, Box<Error>> {
|
||||||
let val = try!(self.eval_expr(&def.value));
|
let val = try!(self.eval_expr(&def.value));
|
||||||
let name = &def.name;
|
let name = &def.name;
|
||||||
match self.out.entry(name.into()) {
|
match self.build_output.entry(name.into()) {
|
||||||
Entry::Occupied(e) => {
|
Entry::Occupied(e) => {
|
||||||
return Err(Box::new(error::Error::new(
|
return Err(Box::new(error::Error::new(
|
||||||
format!(
|
format!(
|
||||||
@ -531,6 +535,21 @@ impl Builder {
|
|||||||
&Statement::Let(ref def) => self.build_let(def),
|
&Statement::Let(ref def) => self.build_let(def),
|
||||||
&Statement::Import(ref def) => self.build_import(def),
|
&Statement::Import(ref def) => self.build_import(def),
|
||||||
&Statement::Expression(ref expr) => self.eval_expr(expr),
|
&Statement::Expression(ref expr) => self.eval_expr(expr),
|
||||||
|
// FIXME(jwall): Stash this into an output slot.
|
||||||
|
// Only one output can be used per file.
|
||||||
|
&Statement::Output(ref typ, ref expr) => {
|
||||||
|
if let None = self.out_lock {
|
||||||
|
let val = try!(self.eval_expr(expr));
|
||||||
|
self.out_lock = Some((typ.fragment.to_string(), val.clone()));
|
||||||
|
Ok(val)
|
||||||
|
} else {
|
||||||
|
Err(Box::new(error::Error::new(
|
||||||
|
format!("You can only have one output per file."),
|
||||||
|
error::ErrorType::DuplicateBinding,
|
||||||
|
typ.pos.clone(),
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -538,8 +557,8 @@ impl Builder {
|
|||||||
if &sym.val == "env" {
|
if &sym.val == "env" {
|
||||||
return Some(self.env.clone());
|
return Some(self.env.clone());
|
||||||
}
|
}
|
||||||
if self.out.contains_key(sym) {
|
if self.build_output.contains_key(sym) {
|
||||||
return Some(self.out[sym].clone());
|
return Some(self.build_output[sym].clone());
|
||||||
}
|
}
|
||||||
if self.assets.contains_key(sym) {
|
if self.assets.contains_key(sym) {
|
||||||
return Some(self.assets[sym].clone());
|
return Some(self.assets[sym].clone());
|
||||||
@ -1138,7 +1157,6 @@ impl Builder {
|
|||||||
// we are not in validate_mode then build_asserts are noops.
|
// we are not in validate_mode then build_asserts are noops.
|
||||||
return Ok(Rc::new(Val::Empty));
|
return Ok(Rc::new(Val::Empty));
|
||||||
}
|
}
|
||||||
// FIXME(jwall): We need to append a semicolon to the expr.
|
|
||||||
let mut expr_as_stmt = String::new();
|
let mut expr_as_stmt = String::new();
|
||||||
let expr = &tok.fragment;
|
let expr = &tok.fragment;
|
||||||
expr_as_stmt.push_str(expr);
|
expr_as_stmt.push_str(expr);
|
||||||
|
@ -369,7 +369,7 @@ fn test_eval_simple_expr() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_eval_simple_lookup_expr() {
|
fn test_eval_simple_lookup_expr() {
|
||||||
let mut b = Builder::new(std::env::current_dir().unwrap());
|
let mut b = Builder::new(std::env::current_dir().unwrap());
|
||||||
b.out
|
b.build_output
|
||||||
.entry(value_node!("var1".to_string(), 1, 0))
|
.entry(value_node!("var1".to_string(), 1, 0))
|
||||||
.or_insert(Rc::new(Val::Int(1)));
|
.or_insert(Rc::new(Val::Int(1)));
|
||||||
test_expr_to_val(
|
test_expr_to_val(
|
||||||
@ -384,7 +384,7 @@ fn test_eval_simple_lookup_expr() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_eval_simple_lookup_error() {
|
fn test_eval_simple_lookup_error() {
|
||||||
let mut b = Builder::new(std::env::current_dir().unwrap());
|
let mut b = Builder::new(std::env::current_dir().unwrap());
|
||||||
b.out
|
b.build_output
|
||||||
.entry(value_node!("var1".to_string(), 1, 0))
|
.entry(value_node!("var1".to_string(), 1, 0))
|
||||||
.or_insert(Rc::new(Val::Int(1)));
|
.or_insert(Rc::new(Val::Int(1)));
|
||||||
let expr = Expression::Simple(Value::Symbol(value_node!("var".to_string(), 1, 1)));
|
let expr = Expression::Simple(Value::Symbol(value_node!("var".to_string(), 1, 1)));
|
||||||
@ -394,7 +394,7 @@ fn test_eval_simple_lookup_error() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_eval_selector_expr() {
|
fn test_eval_selector_expr() {
|
||||||
let mut b = Builder::new(std::env::current_dir().unwrap());
|
let mut b = Builder::new(std::env::current_dir().unwrap());
|
||||||
b.out
|
b.build_output
|
||||||
.entry(value_node!("var1".to_string(), 1, 0))
|
.entry(value_node!("var1".to_string(), 1, 0))
|
||||||
.or_insert(Rc::new(Val::Tuple(vec![(
|
.or_insert(Rc::new(Val::Tuple(vec![(
|
||||||
value_node!("lvl1".to_string(), 1, 0),
|
value_node!("lvl1".to_string(), 1, 0),
|
||||||
@ -403,10 +403,10 @@ fn test_eval_selector_expr() {
|
|||||||
Rc::new(Val::Int(3)),
|
Rc::new(Val::Int(3)),
|
||||||
)])),
|
)])),
|
||||||
)])));
|
)])));
|
||||||
b.out
|
b.build_output
|
||||||
.entry(value_node!("var2".to_string(), 1, 0))
|
.entry(value_node!("var2".to_string(), 1, 0))
|
||||||
.or_insert(Rc::new(Val::Int(2)));
|
.or_insert(Rc::new(Val::Int(2)));
|
||||||
b.out
|
b.build_output
|
||||||
.entry(value_node!("var3".to_string(), 1, 0))
|
.entry(value_node!("var3".to_string(), 1, 0))
|
||||||
.or_insert(Rc::new(Val::Tuple(vec![(
|
.or_insert(Rc::new(Val::Tuple(vec![(
|
||||||
value_node!("lvl1".to_string(), 1, 0),
|
value_node!("lvl1".to_string(), 1, 0),
|
||||||
@ -458,7 +458,7 @@ fn test_eval_selector_expr() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_eval_selector_list_expr() {
|
fn test_eval_selector_list_expr() {
|
||||||
let mut b = Builder::new(std::env::current_dir().unwrap());
|
let mut b = Builder::new(std::env::current_dir().unwrap());
|
||||||
b.out
|
b.build_output
|
||||||
.entry(value_node!("var1".to_string(), 1, 1))
|
.entry(value_node!("var1".to_string(), 1, 1))
|
||||||
.or_insert(Rc::new(Val::List(vec![
|
.or_insert(Rc::new(Val::List(vec![
|
||||||
Rc::new(Val::Str("val1".to_string())),
|
Rc::new(Val::Str("val1".to_string())),
|
||||||
@ -502,7 +502,7 @@ fn test_expr_copy_no_such_tuple() {
|
|||||||
#[should_panic(expected = "Expected Tuple got Int(1)")]
|
#[should_panic(expected = "Expected Tuple got Int(1)")]
|
||||||
fn test_expr_copy_not_a_tuple() {
|
fn test_expr_copy_not_a_tuple() {
|
||||||
let mut b = Builder::new(std::env::current_dir().unwrap());
|
let mut b = Builder::new(std::env::current_dir().unwrap());
|
||||||
b.out
|
b.build_output
|
||||||
.entry(value_node!("tpl1".to_string(), 1, 0))
|
.entry(value_node!("tpl1".to_string(), 1, 0))
|
||||||
.or_insert(Rc::new(Val::Int(1)));
|
.or_insert(Rc::new(Val::Int(1)));
|
||||||
test_expr_to_val(
|
test_expr_to_val(
|
||||||
@ -522,7 +522,7 @@ fn test_expr_copy_not_a_tuple() {
|
|||||||
#[should_panic(expected = "Expected type Integer for field fld1 but got String")]
|
#[should_panic(expected = "Expected type Integer for field fld1 but got String")]
|
||||||
fn test_expr_copy_field_type_error() {
|
fn test_expr_copy_field_type_error() {
|
||||||
let mut b = Builder::new(std::env::current_dir().unwrap());
|
let mut b = Builder::new(std::env::current_dir().unwrap());
|
||||||
b.out
|
b.build_output
|
||||||
.entry(value_node!("tpl1".to_string(), 1, 0))
|
.entry(value_node!("tpl1".to_string(), 1, 0))
|
||||||
.or_insert(Rc::new(Val::Tuple(vec![(
|
.or_insert(Rc::new(Val::Tuple(vec![(
|
||||||
value_node!("fld1".to_string(), 1, 0),
|
value_node!("fld1".to_string(), 1, 0),
|
||||||
@ -550,7 +550,7 @@ fn test_expr_copy_field_type_error() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_expr_copy() {
|
fn test_expr_copy() {
|
||||||
let mut b = Builder::new(std::env::current_dir().unwrap());
|
let mut b = Builder::new(std::env::current_dir().unwrap());
|
||||||
b.out
|
b.build_output
|
||||||
.entry(value_node!("tpl1".to_string(), 1, 0))
|
.entry(value_node!("tpl1".to_string(), 1, 0))
|
||||||
.or_insert(Rc::new(Val::Tuple(vec![(
|
.or_insert(Rc::new(Val::Tuple(vec![(
|
||||||
value_node!("fld1".to_string(), 1, 0),
|
value_node!("fld1".to_string(), 1, 0),
|
||||||
@ -621,7 +621,7 @@ fn test_expr_copy() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_macro_call() {
|
fn test_macro_call() {
|
||||||
let mut b = Builder::new(std::env::current_dir().unwrap());
|
let mut b = Builder::new(std::env::current_dir().unwrap());
|
||||||
b.out
|
b.build_output
|
||||||
.entry(value_node!("tstmac".to_string(), 1, 0))
|
.entry(value_node!("tstmac".to_string(), 1, 0))
|
||||||
.or_insert(Rc::new(Val::Macro(MacroDef {
|
.or_insert(Rc::new(Val::Macro(MacroDef {
|
||||||
argdefs: vec![value_node!("arg1".to_string(), 1, 0)],
|
argdefs: vec![value_node!("arg1".to_string(), 1, 0)],
|
||||||
@ -655,10 +655,10 @@ fn test_macro_call() {
|
|||||||
#[should_panic(expected = "Unable to find arg1")]
|
#[should_panic(expected = "Unable to find arg1")]
|
||||||
fn test_macro_hermetic() {
|
fn test_macro_hermetic() {
|
||||||
let mut b = Builder::new(std::env::current_dir().unwrap());
|
let mut b = Builder::new(std::env::current_dir().unwrap());
|
||||||
b.out
|
b.build_output
|
||||||
.entry(value_node!("arg1".to_string(), 1, 0))
|
.entry(value_node!("arg1".to_string(), 1, 0))
|
||||||
.or_insert(Rc::new(Val::Str("bar".to_string())));
|
.or_insert(Rc::new(Val::Str("bar".to_string())));
|
||||||
b.out
|
b.build_output
|
||||||
.entry(value_node!("tstmac".to_string(), 1, 0))
|
.entry(value_node!("tstmac".to_string(), 1, 0))
|
||||||
.or_insert(Rc::new(Val::Macro(MacroDef {
|
.or_insert(Rc::new(Val::Macro(MacroDef {
|
||||||
argdefs: vec![value_node!("arg2".to_string(), 1, 0)],
|
argdefs: vec![value_node!("arg2".to_string(), 1, 0)],
|
||||||
@ -691,10 +691,10 @@ fn test_macro_hermetic() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_select_expr() {
|
fn test_select_expr() {
|
||||||
let mut b = Builder::new(std::env::current_dir().unwrap());
|
let mut b = Builder::new(std::env::current_dir().unwrap());
|
||||||
b.out
|
b.build_output
|
||||||
.entry(value_node!("foo".to_string(), 1, 0))
|
.entry(value_node!("foo".to_string(), 1, 0))
|
||||||
.or_insert(Rc::new(Val::Str("bar".to_string())));
|
.or_insert(Rc::new(Val::Str("bar".to_string())));
|
||||||
b.out
|
b.build_output
|
||||||
.entry(value_node!("baz".to_string(), 1, 0))
|
.entry(value_node!("baz".to_string(), 1, 0))
|
||||||
.or_insert(Rc::new(Val::Str("boo".to_string())));
|
.or_insert(Rc::new(Val::Str("boo".to_string())));
|
||||||
test_expr_to_val(
|
test_expr_to_val(
|
||||||
@ -753,7 +753,7 @@ fn test_select_expr() {
|
|||||||
#[should_panic(expected = "Expected String but got Integer in Select expression")]
|
#[should_panic(expected = "Expected String but got Integer in Select expression")]
|
||||||
fn test_select_expr_not_a_string() {
|
fn test_select_expr_not_a_string() {
|
||||||
let mut b = Builder::new(std::env::current_dir().unwrap());
|
let mut b = Builder::new(std::env::current_dir().unwrap());
|
||||||
b.out
|
b.build_output
|
||||||
.entry(value_node!("foo".to_string(), 1, 0))
|
.entry(value_node!("foo".to_string(), 1, 0))
|
||||||
.or_insert(Rc::new(Val::Int(4)));
|
.or_insert(Rc::new(Val::Int(4)));
|
||||||
test_expr_to_val(
|
test_expr_to_val(
|
||||||
@ -805,7 +805,7 @@ fn test_build_file_string() {
|
|||||||
let mut b = Builder::new(std::env::current_dir().unwrap());
|
let mut b = Builder::new(std::env::current_dir().unwrap());
|
||||||
b.eval_string("let foo = 1;").unwrap();
|
b.eval_string("let foo = 1;").unwrap();
|
||||||
let key = value_node!("foo".to_string(), 1, 0);
|
let key = value_node!("foo".to_string(), 1, 0);
|
||||||
assert!(b.out.contains_key(&key));
|
assert!(b.build_output.contains_key(&key));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -842,12 +842,29 @@ named!(assert_statement<TokenIter, Statement, error::Error>,
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
named!(out_statement<TokenIter, Statement, error::Error>,
|
||||||
|
do_parse!(
|
||||||
|
word!("out") >>
|
||||||
|
pos: pos >>
|
||||||
|
typ: match_type!(BAREWORD) >>
|
||||||
|
expr: add_return_error!(
|
||||||
|
nom::ErrorKind::Custom(
|
||||||
|
error::Error::new(
|
||||||
|
"Invalid syntax for assert",
|
||||||
|
error::ErrorType::ParseError, pos)),
|
||||||
|
expression) >>
|
||||||
|
punct!(";") >>
|
||||||
|
(Statement::Output(typ.clone(), expr.clone()))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
//trace_macros!(true);
|
//trace_macros!(true);
|
||||||
fn statement(i: TokenIter) -> nom::IResult<TokenIter, Statement, error::Error> {
|
fn statement(i: TokenIter) -> nom::IResult<TokenIter, Statement, error::Error> {
|
||||||
return alt_peek!(i,
|
return alt_peek!(i,
|
||||||
word!("assert") => trace_nom!(assert_statement) |
|
word!("assert") => trace_nom!(assert_statement) |
|
||||||
word!("import") => trace_nom!(import_statement) |
|
word!("import") => trace_nom!(import_statement) |
|
||||||
word!("let") => trace_nom!(let_statement) |
|
word!("let") => trace_nom!(let_statement) |
|
||||||
|
word!("out") => trace_nom!(out_statement) |
|
||||||
trace_nom!(expression_statement)
|
trace_nom!(expression_statement)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -253,7 +253,6 @@ named!(compare_expression<OpListIter, Expression, error::Error>,
|
|||||||
map_res!(
|
map_res!(
|
||||||
do_parse!(
|
do_parse!(
|
||||||
left: alt!(trace_nom!(math_expression) | trace_nom!(parse_expression)) >>
|
left: alt!(trace_nom!(math_expression) | trace_nom!(parse_expression)) >>
|
||||||
// FIXME(jwall): Wrong type of combinator
|
|
||||||
typ: parse_compare_operator >>
|
typ: parse_compare_operator >>
|
||||||
right: alt!(trace_nom!(math_expression) | trace_nom!(parse_expression)) >>
|
right: alt!(trace_nom!(math_expression) | trace_nom!(parse_expression)) >>
|
||||||
(typ, left, right)
|
(typ, left, right)
|
||||||
|
@ -291,6 +291,24 @@ fn test_let_statement_parse() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_out_statement_parse() {
|
||||||
|
assert_error!(out_statement("out"));
|
||||||
|
assert_error!(out_statement("out json"));
|
||||||
|
assert_error!(out_statement("out json foo"));
|
||||||
|
assert_parse!(
|
||||||
|
out_statement("out json 1.0;"),
|
||||||
|
Statement::Output(
|
||||||
|
Token {
|
||||||
|
pos: Position { line: 1, column: 5 },
|
||||||
|
fragment: "json".to_string(),
|
||||||
|
typ: TokenType::BAREWORD
|
||||||
|
},
|
||||||
|
Expression::Simple(Value::Float(value_node!(1.0, 1, 10)))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_expression_statement_parse() {
|
fn test_expression_statement_parse() {
|
||||||
assert_error!(expression_statement("foo"));
|
assert_error!(expression_statement("foo"));
|
||||||
|
@ -253,6 +253,10 @@ named!(asserttok( Span ) -> Token,
|
|||||||
do_tag_tok!(TokenType::BAREWORD, "assert", WS)
|
do_tag_tok!(TokenType::BAREWORD, "assert", WS)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
named!(outtok( Span ) -> Token,
|
||||||
|
do_tag_tok!(TokenType::BAREWORD, "out", WS)
|
||||||
|
);
|
||||||
|
|
||||||
named!(astok( Span ) -> Token,
|
named!(astok( Span ) -> Token,
|
||||||
do_tag_tok!(TokenType::BAREWORD, "as", WS)
|
do_tag_tok!(TokenType::BAREWORD, "as", WS)
|
||||||
);
|
);
|
||||||
@ -359,6 +363,7 @@ named!(token( Span ) -> Token,
|
|||||||
rightsquarebracket |
|
rightsquarebracket |
|
||||||
booleantok |
|
booleantok |
|
||||||
lettok |
|
lettok |
|
||||||
|
outtok |
|
||||||
selecttok |
|
selecttok |
|
||||||
asserttok |
|
asserttok |
|
||||||
macrotok |
|
macrotok |
|
||||||
|
@ -22,6 +22,16 @@ fn test_assert_token() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_out_token() {
|
||||||
|
let result = outtok(LocatedSpan::new("out "));
|
||||||
|
assert!(result.is_done(), format!("result {:?} is not done", result));
|
||||||
|
if let nom::IResult::Done(_, tok) = result {
|
||||||
|
assert_eq!(tok.fragment, "out");
|
||||||
|
assert_eq!(tok.typ, TokenType::BAREWORD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_escape_quoted() {
|
fn test_escape_quoted() {
|
||||||
let result = escapequoted(LocatedSpan::new("foo \\\"bar\""));
|
let result = escapequoted(LocatedSpan::new("foo \\\"bar\""));
|
||||||
@ -103,7 +113,7 @@ fn test_lteqtok() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_tokenize_one_of_each() {
|
fn test_tokenize_one_of_each() {
|
||||||
let result = tokenize(LocatedSpan::new(
|
let result = tokenize(LocatedSpan::new(
|
||||||
"map filter assert let import macro select as => [ ] { } ; = % / * \
|
"map out filter assert let import macro select as => [ ] { } ; = % / * \
|
||||||
+ - . ( ) , 1 . foo \"bar\" // comment\n ; true false == < > <= >= !=",
|
+ - . ( ) , 1 . foo \"bar\" // comment\n ; true false == < > <= >= !=",
|
||||||
));
|
));
|
||||||
assert!(result.is_ok(), format!("result {:?} is not ok", result));
|
assert!(result.is_ok(), format!("result {:?} is not ok", result));
|
||||||
@ -111,8 +121,8 @@ fn test_tokenize_one_of_each() {
|
|||||||
for (i, t) in v.iter().enumerate() {
|
for (i, t) in v.iter().enumerate() {
|
||||||
println!("{}: {:?}", i, t);
|
println!("{}: {:?}", i, t);
|
||||||
}
|
}
|
||||||
assert_eq!(v.len(), 38);
|
assert_eq!(v.len(), 39);
|
||||||
assert_eq!(v[37].typ, TokenType::END);
|
assert_eq!(v[38].typ, TokenType::END);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user