Skip to content

Commit ce28983

Browse files
committed
Matching numbers case insensitively, adding intial tokenizer tests, correcting an issue with OperatorType::BitShiftRight, improvements to error handling, updating roadmap
1 parent ba07249 commit ce28983

File tree

5 files changed

+198
-10
lines changed

5 files changed

+198
-10
lines changed

ROADMAP.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1-
- move ffi (Node.js bridge using Neon) to core project
21
- remove rust-cli, benchmarks
32
- use Node buffers instead of strings
43
- pass transpilation options from cli to core
54
- additional tests for core library
6-
- Test which ES2015 features are not yet covered
5+
- Test and list which ES2015 features are not yet covered
6+
- [ ] Function default parameters
7+
- [ ] Regular expressions
8+
- [ ] Generator functions
9+
- [ ] one-line for loops
10+
- [ ] Template strings
11+
- [ ] Destructing
12+
- ...
713
- implement tests in Rust
814
- implement tests in JS
9-
-> for now, we just return *null* in case of errorsppi
10-
- webpack loader in separate repo
15+
- webpack loader in separate repository
1116
- transform ratel AST to JavaScript AST

core/src/error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ impl fmt::Display for ParseError {
4646
.lines()
4747
.enumerate()
4848
.last()
49-
.expect("Must always have at least one line.");
49+
.unwrap_or((0, ""));
5050

5151
let colno = line.chars().count();
5252
let token_len = source[start..end].chars().count();

core/src/tokenizer.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,9 @@ define_handlers! {
234234
}
235235
},
236236

237-
_ => BSRAssign
237+
b'=' => BSRAssign,
238+
239+
_ => BitShiftRight
238240
}
239241
},
240242

@@ -663,19 +665,36 @@ define_handlers! {
663665

664666
return Ok(Literal(tok.read_binary()));
665667
},
668+
b'B' => {
669+
tok.bump();
670+
671+
return Ok(Literal(tok.read_binary()));
672+
},
666673

667674
b'o' => {
668675
tok.bump();
669676

670677
return Ok(Literal(tok.read_octal()));
671678
},
672679

680+
b'O' => {
681+
tok.bump();
682+
683+
return Ok(Literal(tok.read_octal()));
684+
},
685+
673686
b'x' => {
674687
tok.bump();
675688

676689
return Ok(Literal(tok.read_hexadec()));
677690
},
678691

692+
b'X' => {
693+
tok.bump();
694+
695+
return Ok(Literal(tok.read_hexadec()));
696+
},
697+
679698
_ => {}
680699
}
681700

core/tests/codegen.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,23 @@ fn output_program(input_program: &str) -> String {
1313

1414
macro_rules! assert_compile {
1515
($string:expr, $expect:expr) => {
16-
println!("{:?}", output_program($string));
1716
assert_eq!(output_program($string), $expect.to_string());
1817
}
1918
}
2019

2120
#[test]
2221
fn convert_const_to_var_in_global_scope() {
23-
assert_compile!("const pi = 314;", "var pi=314;");
22+
assert_compile!("const pi = 3.14;", "var pi=3.14;");
2423
}
2524

2625
#[test]
2726
fn convert_let_to_var_in_global_scope() {
28-
assert_compile!("let pi = 314;", "var pi=314;");
27+
assert_compile!("let pi = 3.14;", "var pi=3.14;");
2928
}
3029

3130
#[test]
3231
fn dont_touch_var_in_global_scope() {
33-
assert_compile!("var pi = 314;", "var pi=314;");
32+
assert_compile!("var pi = 3.14;", "var pi=3.14;");
3433
}
3534

3635
#[test]

core/tests/tokenizer.rs

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
extern crate ratel;
2+
3+
pub use ratel::*;
4+
pub use ratel::grammar::*;
5+
pub use ratel::tokenizer::*;
6+
pub use ratel::lexicon::Token;
7+
pub use ratel::lexicon::ReservedKind;
8+
pub use ratel::lexicon::Token::*;
9+
pub use ratel::owned_slice::OwnedSlice;
10+
11+
fn test_token(input: &str, expected: Token) -> bool {
12+
let mut tokenizer = Tokenizer::new(&input);
13+
let tok = tokenizer.get_token().unwrap();
14+
if tok != expected {
15+
println!("\n{:?}\n", tok);
16+
}
17+
tok == expected
18+
}
19+
20+
macro_rules! assert_token {
21+
($string:expr, $token:expr, $descr:expr) => {
22+
assert_eq!(test_token($string, $token), true, $descr);
23+
}
24+
}
25+
26+
#[test]
27+
fn test_tokenizer_chars() {
28+
assert_token!(";", Token::Semicolon, "read a Token::Semicolon");
29+
assert_token!(":", Token::Colon, "read a Token::Colon");
30+
assert_token!(",", Token::Comma, "read a Token::Comma");
31+
assert_token!("(", Token::ParenOpen, "read a Token::ParenOpen");
32+
assert_token!(")", Token::ParenClose, "read a Token::ParenClose");
33+
assert_token!("[", Token::BracketOpen, "read a Token::BracketOpen");
34+
assert_token!("]", Token::BracketClose, "read a Token::BracketClose");
35+
assert_token!("{", Token::BraceOpen, "read a Token::BraceOpen");
36+
assert_token!("}", Token::BraceClose, "read a Token::BraceClose");
37+
}
38+
39+
#[test]
40+
fn test_tokenizer_control_statements() {
41+
assert_token!("break", Token::Break, "read a Token::Break");
42+
assert_token!("do", Token::Do, "read a Token::Do");
43+
assert_token!("case", Token::Case, "read a Token::Case");
44+
assert_token!("else", Token::Else, "read a Token::Else");
45+
assert_token!("catch", Token::Catch, "read a Token::Catch");
46+
assert_token!("export", Token::Export, "read a Token::Export");
47+
assert_token!("class", Token::Class, "read a Token::Class");
48+
assert_token!("extends", Token::Extends, "read a Token::Extends");
49+
assert_token!("return", Token::Return, "read a Token::Return");
50+
assert_token!("while", Token::While, "read a Token::While");
51+
assert_token!("finally", Token::Finally, "read a Token::Finally");
52+
assert_token!("super", Token::Super, "read a Token::Super");
53+
assert_token!("with", Token::With, "read a Token::With");
54+
assert_token!("continue", Token::Continue, "read a Token::Continue");
55+
assert_token!("for", Token::For, "read a Token::For");
56+
assert_token!("switch", Token::Switch, "read a Token::Switch");
57+
assert_token!("yield", Token::Yield, "read a Token::Yield");
58+
assert_token!("debugger", Token::Debugger, "read a Token::Debugger");
59+
assert_token!("function", Token::Function, "read a Token::Function");
60+
assert_token!("this", Token::This, "read a Token::This");
61+
assert_token!("default", Token::Default, "read a Token::Default");
62+
assert_token!("if", Token::If, "read a Token::If");
63+
assert_token!("throw", Token::Throw, "read a Token::Throw");
64+
assert_token!("import", Token::Import, "read a Token::Import");
65+
assert_token!("try", Token::Try, "read a Token::Try");
66+
}
67+
68+
#[test]
69+
fn test_tokenizer_operators() {
70+
assert_token!("=>", Token::Operator(OperatorType::FatArrow), "OperatorType::FatArrow");
71+
assert_token!(".", Token::Operator(OperatorType::Accessor), "OperatorType::Accessor");
72+
assert_token!("new", Token::Operator(OperatorType::New), "OperatorType::New");
73+
assert_token!("++", Token::Operator(OperatorType::Increment), "OperatorType::Increment");
74+
assert_token!("--", Token::Operator(OperatorType::Decrement), "OperatorType::Decrement");
75+
assert_token!("!", Token::Operator(OperatorType::LogicalNot), "OperatorType::LogicalNot");
76+
assert_token!("~", Token::Operator(OperatorType::BitwiseNot), "OperatorType::BitwiseNot");
77+
assert_token!("typeof", Token::Operator(OperatorType::Typeof), "OperatorType::Typeof");
78+
assert_token!("void", Token::Operator(OperatorType::Void), "OperatorType::Void");
79+
assert_token!("delete", Token::Operator(OperatorType::Delete), "OperatorType::Delete");
80+
assert_token!("*", Token::Operator(OperatorType::Multiplication), "OperatorType::Multiplication");
81+
assert_token!("/", Token::Operator(OperatorType::Division), "OperatorType::Division");
82+
assert_token!("%", Token::Operator(OperatorType::Remainder), "OperatorType::Remainder");
83+
assert_token!("**", Token::Operator(OperatorType::Exponent), "OperatorType::Exponent");
84+
assert_token!("+", Token::Operator(OperatorType::Addition), "OperatorType::Addition");
85+
assert_token!("-", Token::Operator(OperatorType::Substraction), "OperatorType::Substraction");
86+
assert_token!("<<", Token::Operator(OperatorType::BitShiftLeft), "OperatorType::BitShiftLeft");
87+
assert_token!(">>", Token::Operator(OperatorType::BitShiftRight), "OperatorType::BitShiftRight");
88+
assert_token!(">>>", Token::Operator(OperatorType::UBitShiftRight), "OperatorType::UBitShiftRight");
89+
assert_token!("<", Token::Operator(OperatorType::Lesser), "OperatorType::Lesser");
90+
assert_token!("<=", Token::Operator(OperatorType::LesserEquals), "OperatorType::LesserEquals");
91+
assert_token!(">", Token::Operator(OperatorType::Greater), "OperatorType::Greater");
92+
assert_token!(">=", Token::Operator(OperatorType::GreaterEquals), "OperatorType::GreaterEquals");
93+
assert_token!("instanceof", Token::Operator(OperatorType::Instanceof), "OperatorType::Instanceof");
94+
assert_token!("in", Token::Operator(OperatorType::In), "OperatorType::In");
95+
assert_token!("===", Token::Operator(OperatorType::StrictEquality), "OperatorType::StrictEquality");
96+
assert_token!("!==", Token::Operator(OperatorType::StrictInequality), "OperatorType::StrictInequality");
97+
assert_token!("==", Token::Operator(OperatorType::Equality), "OperatorType::Equality");
98+
assert_token!("!=", Token::Operator(OperatorType::Inequality), "OperatorType::Inequality");
99+
assert_token!("&", Token::Operator(OperatorType::BitwiseAnd), "OperatorType::BitwiseAnd");
100+
assert_token!("^", Token::Operator(OperatorType::BitwiseXor), "OperatorType::BitwiseXor");
101+
assert_token!("|", Token::Operator(OperatorType::BitwiseOr), "OperatorType::BitwiseOr");
102+
assert_token!("&&", Token::Operator(OperatorType::LogicalAnd), "OperatorType::LogicalAnd");
103+
assert_token!("||", Token::Operator(OperatorType::LogicalOr), "OperatorType::LogicalOr");
104+
assert_token!("?", Token::Operator(OperatorType::Conditional), "OperatorType::Conditional");
105+
assert_token!("=", Token::Operator(OperatorType::Assign), "OperatorType::Assign");
106+
assert_token!("+=", Token::Operator(OperatorType::AddAssign), "OperatorType::AddAssign");
107+
assert_token!("-=", Token::Operator(OperatorType::SubstractAssign), "OperatorType::SubstractAssign");
108+
assert_token!("**=", Token::Operator(OperatorType::ExponentAssign), "OperatorType::ExponentAssign");
109+
assert_token!("*=", Token::Operator(OperatorType::MultiplyAssign), "OperatorType::MultiplyAssign");
110+
assert_token!("/=", Token::Operator(OperatorType::DivideAssign), "OperatorType::DivideAssign");
111+
assert_token!("%=", Token::Operator(OperatorType::RemainderAssign), "OperatorType::RemainderAssign");
112+
assert_token!("<<=", Token::Operator(OperatorType::BSLAssign), "OperatorType::BSLAssign");
113+
assert_token!(">>=", Token::Operator(OperatorType::BSRAssign), "OperatorType::BSRAssign");
114+
assert_token!(">>>=", Token::Operator(OperatorType::UBSRAssign), "OperatorType::UBSRAssign");
115+
assert_token!("&=", Token::Operator(OperatorType::BitAndAssign), "OperatorType::BitAndAssign");
116+
assert_token!("^=", Token::Operator(OperatorType::BitXorAssign), "OperatorType::BitXorAssign");
117+
assert_token!("|=", Token::Operator(OperatorType::BitOrAssign), "OperatorType::BitOrAssign");
118+
assert_token!("...", Token::Operator(OperatorType::Spread), "OperatorType::Spread");
119+
}
120+
121+
#[test]
122+
fn test_tokenizer_literals() {
123+
assert_token!("undefined", Token::Literal(LiteralValue::LiteralUndefined), "Token::LiteralUndefined");
124+
assert_token!("null", Token::Literal(LiteralValue::LiteralNull), "Token::LiteralNull");
125+
assert_token!("true", Token::Literal(LiteralValue::LiteralTrue), "Token::LiteralTrue");
126+
assert_token!("false", Token::Literal(LiteralValue::LiteralFalse), "Token::LiteralFalse");
127+
128+
assert_token!("'foo'", Token::Literal(LiteralString(OwnedSlice::from_static("'foo'"))), "Token::LiteralString");
129+
assert_token!("\"foo\"", Token::Literal(LiteralString(OwnedSlice::from_static("\"foo\""))), "Token::LiteralString");
130+
131+
// assert_token!("2.2", Token::Literal(LiteralNumber(OwnedSlice::from_static("2.2"))), "Token::LiteralNumber");
132+
assert_token!("2.2", Token::Literal(LiteralFloat(OwnedSlice::from_static("2.2"))), "Token::LiteralFloat");
133+
134+
// will be deprecated in favor of LiteralNumber
135+
assert_token!("2", Token::Literal(LiteralFloat(OwnedSlice::from_static("2"))), "Token::LiteralFloat");
136+
// assert_token!("2", Token::Literal(LiteralInteger(2)), "Token::LiteralInteger");
137+
138+
assert_token!("0xff", Token::Literal(LiteralInteger(255)), "Token::LiteralInteger");
139+
assert_token!("0XFF", Token::Literal(LiteralInteger(255)), "Token::LiteralInteger");
140+
assert_token!("0b01001011", Token::Literal(LiteralInteger(75)), "Token::LiteralInteger");
141+
assert_token!("0B01001011", Token::Literal(LiteralInteger(75)), "Token::LiteralInteger");
142+
assert_token!("0o113", Token::Literal(LiteralInteger(75)), "Token::LiteralInteger");
143+
assert_token!("0O113", Token::Literal(LiteralInteger(75)), "Token::LiteralInteger");
144+
}
145+
146+
#[test]
147+
fn test_tokenizer_reserved() {
148+
assert_token!("enum", Token::Reserved(ReservedKind::Enum), "ReservedKind::Enum");
149+
assert_token!("implements", Token::Reserved(ReservedKind::Implements), "ReservedKind::Implements");
150+
assert_token!("package", Token::Reserved(ReservedKind::Package), "ReservedKind::Package");
151+
assert_token!("protected", Token::Reserved(ReservedKind::Protected), "ReservedKind::Protected");
152+
assert_token!("interface", Token::Reserved(ReservedKind::Interface), "ReservedKind::Interface");
153+
assert_token!("private", Token::Reserved(ReservedKind::Private), "ReservedKind::Private");
154+
assert_token!("public", Token::Reserved(ReservedKind::Public), "ReservedKind::Public");
155+
}
156+
157+
158+
#[test]
159+
fn test_tokenizer_whitespace() {
160+
assert_token!("", Token::EndOfProgram, "empty string");
161+
assert_token!(" ", Token::EndOfProgram, "whitespaces");
162+
assert_token!("\n\n\n ", Token::EndOfProgram, "newlines");
163+
assert_token!("//Comment\n//Comment", Token::EndOfProgram, "single-line comment");
164+
assert_token!("/**\n * Comment\n */", Token::EndOfProgram, "multi-line comment");
165+
}

0 commit comments

Comments
 (0)