Skip to content
This repository was archived by the owner on Jun 15, 2023. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .depend
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ src/reactjs_jsx_ppx_v3.cmx : src/reactjs_jsx_ppx_v3.cmi
src/reactjs_jsx_ppx_v3.cmi :
src/res_ast_conversion.cmx : src/res_printer.cmx src/res_ast_conversion.cmi
src/res_ast_conversion.cmi :
src/res_ast_debugger.cmx : src/res_driver.cmx src/res_doc.cmx \
src/res_ast_debugger.cmi
src/res_ast_debugger.cmx : src/res_string.cmx src/res_driver.cmx \
src/res_doc.cmx src/res_ast_debugger.cmi
src/res_ast_debugger.cmi : src/res_driver.cmi
src/res_cli.cmx : src/res_driver_reason_binary.cmx \
src/res_driver_ml_parser.cmx src/res_driver_binary.cmx src/res_driver.cmx \
Expand Down Expand Up @@ -61,7 +61,7 @@ src/res_parser.cmi : src/res_token.cmx src/res_scanner.cmi \
src/res_comment.cmi
src/res_parsetree_viewer.cmx : src/res_parsetree_viewer.cmi
src/res_parsetree_viewer.cmi :
src/res_printer.cmx : src/res_utf8.cmx src/res_token.cmx \
src/res_printer.cmx : src/res_utf8.cmx src/res_token.cmx src/res_string.cmx \
src/res_parsetree_viewer.cmx src/res_parens.cmx src/res_doc.cmx \
src/res_comments_table.cmx src/res_comment.cmx src/res_printer.cmi
src/res_printer.cmi : src/res_doc.cmi src/res_comments_table.cmx \
Expand All @@ -70,6 +70,8 @@ src/res_reporting.cmx : src/res_token.cmx src/res_grammar.cmx
src/res_scanner.cmx : src/res_utf8.cmx src/res_token.cmx \
src/res_diagnostics.cmx src/res_comment.cmx src/res_scanner.cmi
src/res_scanner.cmi : src/res_token.cmx src/res_diagnostics.cmi
src/res_string.cmx : src/res_string.cmi
src/res_string.cmi :
src/res_token.cmx : src/res_comment.cmx
src/res_utf8.cmx : src/res_utf8.cmi
src/res_utf8.cmi :
Expand Down
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ depend:
API_FILES = \
src/reactjs_jsx_ppx_v3.cmx\
src/res_io.cmx\
src/res_string.cmx\
src/res_minibuffer.cmx\
src/res_doc.cmx\
src/res_comment.cmx\
Expand Down Expand Up @@ -46,7 +47,7 @@ TEST_FILES = $(API_FILES) tests/res_utf8_test.cmx tests/res_test.cmx
.DEFAULT_GOAL := build-native

lib/rescript.exe: $(CLI_FILES)
$(OCAMLOPT) $(OCAMLFLAGS) -O2 -o ./lib/rescript.exe -I +compiler-libs ocamlcommon.cmxa -I src $(CLI_FILES)
$(OCAMLOPT) $(OCAMLFLAGS) -O2 -o ./lib/rescript.exe -I +compiler-libs ocamlcommon.cmxa str.cmxa -I src $(CLI_FILES)

build-native: lib/refmt.exe lib/rescript.exe depend

Expand All @@ -69,7 +70,7 @@ benchmarks/refmt_main3b.cmx: benchmarks/refmt_main3b.ml
$(OCAMLOPT) -c -O2 -I +compiler-libs ocamlcommon.cmxa benchmarks/refmt_main3b.ml

lib/test.exe: $(TEST_FILES)
$(OCAMLOPT) $(OCAMLFLAGS) -O2 -o ./lib/test.exe -bin-annot -I +compiler-libs ocamlcommon.cmxa -I src -I tests $(TEST_FILES)
$(OCAMLOPT) $(OCAMLFLAGS) -O2 -o ./lib/test.exe -bin-annot -I +compiler-libs ocamlcommon.cmxa str.cmxa -I src -I tests $(TEST_FILES)

test: reanalyze build-native lib/test.exe
./lib/test.exe
Expand Down
2 changes: 1 addition & 1 deletion src/res_ast_debugger.ml
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ module SexpAst = struct
| Pconst_string (txt, tag) ->
Sexp.list [
Sexp.atom "Pconst_string";
string txt;
string (Res_string.convertDecEscapes txt);
match tag with
| Some txt -> Sexp.list [
Sexp.atom "Some";
Expand Down
33 changes: 2 additions & 31 deletions src/res_core.ml
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,6 @@ type stringLiteralState =
| Start
| Backslash
| HexEscape
| DecimalEscape
| OctalEscape
| UnicodeEscape
| UnicodeCodePointEscape
| UnicodeEscapeStart
Expand Down Expand Up @@ -500,7 +498,7 @@ let parseStringLiteral s =
let rec parse state i d =
if i = len then
(match state with
| HexEscape | DecimalEscape | OctalEscape | UnicodeEscape | UnicodeCodePointEscape -> false
| HexEscape | UnicodeEscape | UnicodeCodePointEscape -> false
| _ -> true)
else
let c = String.unsafe_get s i in
Expand All @@ -515,11 +513,10 @@ let parseStringLiteral s =
| 'r' -> Buffer.add_char b '\r'; parse Start (i + 1) d
| 'b' -> Buffer.add_char b '\008'; parse Start (i + 1) d
| 't' -> Buffer.add_char b '\009'; parse Start (i + 1) d
| '0' -> Buffer.add_char b '\000'; parse Start (i + 1) d
| ('\\' | ' ' | '\'' | '"') as c -> Buffer.add_char b c; parse Start (i + 1) d
| 'x' -> parse HexEscape (i + 1) 0
| 'o' -> parse OctalEscape (i + 1) 0
| 'u' -> parse UnicodeEscapeStart (i + 1) 0
| '0' .. '9' -> parse DecimalEscape i 0
| '\010' | '\013' -> parse EscapedLineBreak (i + 1) d
| c -> Buffer.add_char b '\\'; Buffer.add_char b c; parse Start (i + 1) d)
| HexEscape ->
Expand All @@ -534,32 +531,6 @@ let parseStringLiteral s =
)
else
parse HexEscape (i + 1) (d + 1)
| DecimalEscape ->
if d == 2 then
let c0 = String.unsafe_get s (i - 2) in
let c1 = String.unsafe_get s (i - 1) in
let c2 = String.unsafe_get s i in
let c = 100 * (Char.code c0 - 48) + 10 * (Char.code c1 - 48) + (Char.code c2 - 48) in
if c < 0 || c > 255 then false
else (
Buffer.add_char b (Char.unsafe_chr c);
parse Start (i + 1) 0
)
else
parse DecimalEscape (i + 1) (d + 1)
| OctalEscape ->
if d == 2 then
let c0 = String.unsafe_get s (i - 2) in
let c1 = String.unsafe_get s (i - 1) in
let c2 = String.unsafe_get s i in
let c = 64 * (Char.code c0 - 48) + 8 * (Char.code c1 - 48) + (Char.code c2 - 48) in
if c < 0 || c > 255 then false
else (
Buffer.add_char b (Char.unsafe_chr c);
parse Start (i + 1) 0
)
else
parse OctalEscape (i + 1) (d + 1)
| UnicodeEscapeStart ->
(match c with
| '{' -> parse UnicodeCodePointEscape (i + 1) 0
Expand Down
2 changes: 1 addition & 1 deletion src/res_printer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ let printStringLoc sloc cmtTbl =
printComments doc cmtTbl sloc.loc

let printStringContents txt =
let lines = String.split_on_char '\n' txt in
let lines = String.split_on_char '\n' (Res_string.convertDecEscapes txt) in
Doc.join ~sep:Doc.literalLine (List.map Doc.text lines)

let printConstant ?(templateLiteral=false) c = match c with
Expand Down
21 changes: 15 additions & 6 deletions src/res_scanner.ml
Original file line number Diff line number Diff line change
Expand Up @@ -328,13 +328,22 @@ let scanStringEscapeSequence ~startPos scanner =
(* \ already consumed *)
| 'n' | 't' | 'b' | 'r' | '\\' | ' ' | '\'' | '"' ->
next scanner
| '0'..'9' ->
(* decimal *)
scan ~n:3 ~base:10 ~max:255
| 'o' ->
(* octal *)
| '0' ->
next scanner;
scan ~n:3 ~base:8 ~max:255
let nextCharIsDecimalDigit =
match scanner.ch with
| '0' .. '9' -> true
| _ -> false
in
if nextCharIsDecimalDigit then
let pos = position scanner in
let msg = "The only valid numeric escape in strict mode is '\\0'" in
scanner.err ~startPos ~endPos:pos (Diagnostics.message msg)
| '1'..'9' ->
let pos = position scanner in
let msg = "The only valid numeric escape in strict mode is '\\0'" in
scanner.err ~startPos ~endPos:pos (Diagnostics.message msg);
next scanner
| 'x' ->
(* hex *)
next scanner;
Expand Down
14 changes: 14 additions & 0 deletions src/res_string.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
let hexTable = [|'0'; '1'; '2'; '3'; '4'; '5'; '6'; '7'; '8'; '9'; 'a'; 'b'; 'c'; 'd'; 'e'; 'f'|]

let convertDecEscapes txt =
let regex = Str.regexp "\\\\[0-9][0-9][0-9]" in
let convertEscape s =
let strNum = Str.string_after (Str.matched_string s) 1 in
try
let intNum = int_of_string strNum in
let c1 = Array.get hexTable (intNum lsr 4) in
let c2 = Array.get hexTable (intNum land 15) in
"\\x" ^ String.concat "" [ String.make 1 c1; String.make 1 c2 ]
with _ -> s (* in theory this should never happen *)
in
Str.global_substitute regex convertEscape txt
1 change: 1 addition & 0 deletions src/res_string.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
val convertDecEscapes: string -> string
1 change: 1 addition & 0 deletions test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ done

# printing
for file in tests/{printer,conversion}/**/*.(res|resi|ml|mli); do
# NOTE: this results in .ml(i) files being printed using .res(i) syntax
lib/rescript.exe $file &> $(exp $file) & maybeWait
done
for file in tests/{printer,conversion}/**/*.re; do
Expand Down
Binary file not shown.
24 changes: 24 additions & 0 deletions tests/parsing/errors/expressions/expected/stringLiteral.res.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

Syntax error!
tests/parsing/errors/expressions/stringLiteral.res:2:4-5

1 │ switch x {
2 │ | "\055" => ()
3 │ | "\123" => ()
4 │ }

The only valid numeric escape in strict mode is '\0'


Syntax error!
tests/parsing/errors/expressions/stringLiteral.res:3:4

1 │ switch x {
2 │ | "\055" => ()
3 │ | "\123" => ()
4 │ }
5 │

The only valid numeric escape in strict mode is '\0'

;;match x with | {js|\055|js} -> () | {js|\123|js} -> ()
1 change: 1 addition & 0 deletions tests/parsing/errors/expressions/object.res
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let obj = {"\055": "octal escape", "\123": "another octal escape"}
4 changes: 4 additions & 0 deletions tests/parsing/errors/expressions/stringLiteral.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
switch x {
| "\055" => ()
| "\123" => ()
}
4 changes: 2 additions & 2 deletions tests/parsing/errors/scanner/escapeSequence.res
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
let x = "\0"
let x = "\055"

let x = "\oAAA"
let x = "\123"
18 changes: 9 additions & 9 deletions tests/parsing/errors/scanner/expected/escapeSequence.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@
Syntax error!
tests/parsing/errors/scanner/escapeSequence.res:1:10-11

1 │ let x = "\0"
1 │ let x = "\055"
2 │
3 │ let x = "\oAAA"
3 │ let x = "\123"

unknown escape sequence
The only valid numeric escape in strict mode is '\0'


Syntax error!
tests/parsing/errors/scanner/escapeSequence.res:3:10-11
tests/parsing/errors/scanner/escapeSequence.res:3:10

1 │ let x = "\0"
1 │ let x = "\055"
2 │
3 │ let x = "\oAAA"
3 │ let x = "\123"
4 │

unknown escape sequence
The only valid numeric escape in strict mode is '\0'

let x = {js|\0|js}
let x = {js|\oAAA|js}
let x = {js|\055|js}
let x = {js|\123|js}
3 changes: 3 additions & 0 deletions tests/parsing/grammar/expressions/bsObject.res
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
let zero = 0

let x = {"age": 30}
let y = {"age": 30,}
let y = {"age": 30, "name": "steve"}
let y = {"age": 30, "name": "steve",}
let z = {"\xff": 1, "\u2212": "two", "\0": zero, "\o123": "o123"}

// don't confuse with start of block expr
let x = {"age"}
Expand Down
9 changes: 3 additions & 6 deletions tests/parsing/grammar/expressions/constants.res
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,15 @@ let x = '\t'
let x = '\b'
let x = '\r'
let x = ' '
let x = '\o021'
let x = '\xAA'
let x = '\179'

let () = {
getResult()
-10
}

let x = "foo\010bar"
let x = "foo\0bar"
let x = "foo\x0Abar"
let x = "foo\o012bar"
let x = "\\abc"
let x = "\'bar"
let x = "\nbar"
Expand All @@ -81,13 +78,13 @@ let x = "\u2665"
let a = "\u{000000000061}"
let x = "\u{00A9}"
let x = "\u{00a9}"
let x = "\oAAA" // same as "oAAA" since \o is not a valid escape
let x = "\m" // same as "m" since \m is not a valid escape
let smile = "\u{1F600}"
let smile = "\u{1f600}"
let smile = "\240\159\152\128"

// represent the same thing
let u = "日本語"
let u = "\u65e5\u672c\u8a9e"
let u = "\u{000065e5}\u{0000672c}\u{00008a9e}"
let u = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"
let u = "\230\151\165\230\156\172\232\170\158"
3 changes: 3 additions & 0 deletions tests/parsing/grammar/expressions/expected/bsObject.res.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
let zero = 0
let x = [%obj { age = 30 }]
let y = [%obj { age = 30 }]
let y = [%obj { age = 30; name = {js|steve|js} }]
let y = [%obj { age = 30; name = {js|steve|js} }]
let z =
[%obj { � = 1; \u2212 = {js|two|js}; \0 = zero; \o123 = {js|o123|js} }]
let x = (("age")[@ns.braces ])
let x = (("age".(0))[@ns.braces ])
let x = (("age" |. Js.log)[@ns.braces ])
Expand Down
11 changes: 4 additions & 7 deletions tests/parsing/grammar/expressions/expected/constants.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,10 @@ let x = '\t'
let x = '\b'
let x = '\r'
let x = ' '
let x = '\017'
let x = '\170'
let x = '\179'
let () = ((getResult (); (-10))[@ns.braces ])
let x = {js|foo\010bar|js}
let x = {js|foo\0bar|js}
let x = {js|foo\x0Abar|js}
let x = {js|foo\o012bar|js}
let x = {js|\\abc|js}
let x = {js|\'bar|js}
let x = {js|\nbar|js}
Expand All @@ -66,11 +63,11 @@ let x = {js|\u2665|js}
let a = {js|\u{000000000061}|js}
let x = {js|\u{00A9}|js}
let x = {js|\u{00a9}|js}
let x = {js|\oAAA|js}
let x = {js|\m|js}
let smile = {js|\u{1F600}|js}
let smile = {js|\u{1f600}|js}
let smile = {js|\240\159\152\128|js}
let u = {js|日本語|js}
let u = {js|\u65e5\u672c\u8a9e|js}
let u = {js|\u{000065e5}\u{0000672c}\u{00008a9e}|js}
let u = {js|\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e|js}
let u = {js|\230\151\165\230\156\172\232\170\158|js}
let u = {js|\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e|js}
4 changes: 4 additions & 0 deletions tests/parsing/grammar/pattern/constant.res
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ switch x {
| "stringPattern" => ()
| "stringPattern" as s => ()
| ("stringPattern" : string) as s => ()
| "\xff" => ()
| "\u2212" => ()
| "\0" => ()
| "\o123" => ()
}

for "stringPattern" in 0 to 10 { () }
Expand Down
4 changes: 4 additions & 0 deletions tests/parsing/grammar/pattern/expected/constant.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ let ({js|stringPattern|js} : string) as s = ()
| {js|stringPattern|js} -> ()
| {js|stringPattern|js} as s -> ()
| ({js|stringPattern|js} : string) as s -> ()
| {js|\xff|js} -> ()
| {js|\u2212|js} -> ()
| {js|\0|js} -> ()
| {js|\o123|js} -> ()
;;for {js|stringPattern|js} = 0 to 10 do () done
;;for {js|stringPattern|js} as s = 0 to 10 do () done
;;for {js|stringPattern|js} = 0 to 10 do () done
Expand Down
Loading