瀏覽代碼

fixed string escaping.

Nicolas Cannasse 19 年之前
父節點
當前提交
029c2d5ac0
共有 4 個文件被更改,包括 45 次插入49 次删除
  1. 37 0
      ast.ml
  2. 1 4
      genneko.ml
  3. 1 43
      genswf8.ml
  4. 6 2
      lexer.mll

+ 37 - 0
ast.ml

@@ -228,6 +228,8 @@ let s_escape s =
 		| '\n' -> Buffer.add_string b "\\n"
 		| '\t' -> Buffer.add_string b "\\t"
 		| '\r' -> Buffer.add_string b "\\r"
+		| '"' -> Buffer.add_string b "\\\""
+		| '\\' -> Buffer.add_string b "\\\\"
 		| c -> Buffer.add_char b c
 	done;
 	Buffer.contents b
@@ -325,3 +327,38 @@ let s_token = function
 	| Arrow -> "->"
 	| IntInterval s -> s ^ "..."
 	| Macro s -> "#" ^ s
+
+let unescape s = 
+	let b = Buffer.create 0 in
+	let rec loop esc i =
+		if i = String.length s then
+			()
+		else
+			let c = s.[i] in
+			if esc then begin
+				let inext = ref (i + 1) in
+				(match c with
+				| 'n' -> Buffer.add_char b '\n'
+				| 'r' -> Buffer.add_char b '\r'
+				| 't' -> Buffer.add_char b '\t'
+				| '"' | '\'' | '\\' -> Buffer.add_char b c
+				| '0'..'3' ->
+					let c = (try char_of_int (int_of_string ("0o" ^ String.sub s i 3)) with _ -> raise Exit) in
+					Buffer.add_char b c;
+					inext := !inext + 2;
+				| 'x' ->
+					let c = (try char_of_int (int_of_string ("0x" ^ String.sub s (i+1) 2)) with _ -> raise Exit) in
+					Buffer.add_char b c;
+					inext := !inext + 2;
+				| _ ->
+					raise Exit);
+				loop false !inext;
+			end else
+				match c with
+				| '\\' -> loop true (i + 1)
+				| c ->
+					Buffer.add_char b c;
+					loop false (i + 1)
+	in
+	loop false 0;
+	Buffer.contents b

+ 1 - 4
genneko.ml

@@ -387,9 +387,6 @@ let generate file types =
 	let e = (EBlock (packs @ methods @ boot :: vars), null_pos) in
 	let neko_file = Filename.chop_extension file ^ ".neko" in
 	let ch = IO.output_channel (open_out neko_file) in
-	Nxml.write ch (Nxml.to_xml e);
+	(if !Plugin.verbose then Nxml.write_fmt else Nxml.write) ch (Nxml.to_xml e);
 	IO.close_out ch;
 	if Sys.command ("nekoc " ^ neko_file) = 0 && not (!Plugin.verbose) then Sys.remove neko_file
-
-;;
-Nast.do_escape := false

+ 1 - 43
genswf8.ml

@@ -438,53 +438,11 @@ let no_value ctx retval =
 (* -------------------------------------------------------------- *)
 (* Generation *)
 
-let unescape_chars s p = 
-	let b = Buffer.create 0 in
-	let rec loop esc i =
-		if i = String.length s then
-			()
-		else
-			let c = s.[i] in
-			if esc then begin
-				let inext = ref (i + 1) in
-				(match c with
-				| 'n' -> Buffer.add_char b '\n'
-				| 'r' -> Buffer.add_char b '\r'
-				| 't' -> Buffer.add_char b '\t'
-				| '"' | '\'' | '\\' -> Buffer.add_char b c
-				| '0'..'3' ->
-					let c = (try
-						char_of_int (int_of_string ("0o" ^ String.sub s i 3))
-					with _ ->
-						raise (Lexer.Error (Lexer.Invalid_character c,p))
-					) in
-					Buffer.add_char b c;
-					inext := !inext + 2;
-				| 'x' ->
-					let c = (try
-						char_of_int (int_of_string ("0x" ^ String.sub s (i+1) 2))
-					with _ ->
-						raise (Lexer.Error (Lexer.Invalid_character c,p))
-					) in
-					Buffer.add_char b c;
-					inext := !inext + 2;
-				| _ -> raise (Lexer.Error (Lexer.Invalid_character c,p)));
-				loop false !inext;
-			end else
-				match c with
-				| '\\' -> loop true (i + 1)
-				| c ->
-					Buffer.add_char b c;
-					loop false (i + 1)
-	in
-	loop false 0;
-	Buffer.contents b
-
 let rec gen_constant ctx c p =
 	match c with
 	| TInt s -> (try push ctx [VInt32 (Int32.of_string s)] with _ -> gen_constant ctx (TFloat s) p)
 	| TFloat s -> push ctx [VFloat (try float_of_string s with _ -> error p)]
-	| TString s -> push ctx [VStr (unescape_chars s p)]
+	| TString s -> push ctx [VStr s]
 	| TBool b -> write ctx (APush [PBool b])
 	| TNull -> push ctx [VNull]
 	| TThis

+ 6 - 2
lexer.mll

@@ -25,6 +25,7 @@ type error_msg =
 	| Invalid_character of char
 	| Unterminated_string
 	| Unclosed_comment
+	| Invalid_escape
 
 exception Error of error_msg * pos
 
@@ -33,6 +34,7 @@ let error_msg = function
 	| Invalid_character c -> Printf.sprintf "Invalid character 0x%.2X" (int_of_char c)
 	| Unterminated_string -> "Unterminated string"
 	| Unclosed_comment -> "Unclosed comment"
+	| Invalid_escape -> "Invalid escape sequence"
 
 let cur_file = ref ""
 let all_lines = Hashtbl.create 0
@@ -194,13 +196,15 @@ rule token = parse
 			reset();
 			let pmin = lexeme_start lexbuf in
 			let pmax = (try string lexbuf with Exit -> error Unterminated_string pmin) in
-			mk_tok (Const (String (contents()))) pmin pmax;
+			let str = (try unescape (contents()) with Exit -> error Invalid_escape pmin) in
+			mk_tok (Const (String str)) pmin pmax;
 		}
 	| "'" {
 			reset();
 			let pmin = lexeme_start lexbuf in
 			let pmax = (try string2 lexbuf with Exit -> error Unterminated_string pmin) in
-			mk_tok (Const (String (contents()))) pmin pmax;
+			let str = (try unescape (contents()) with Exit -> error Invalid_escape pmin) in
+			mk_tok (Const (String str)) pmin pmax;
 		}
 	| '#' ident { 
 			let v = lexeme lexbuf in