Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
Checking mergeability… Don't worry, you can still create the pull request.
  • 2 commits
  • 4 files changed
  • 0 commit comments
  • 1 contributor
Commits on Apr 04, 2012
@rvirding Fix scanning of strings 7945c56
Commits on Apr 05, 2012
@rvirding Fix string library functions
string.byte, string.char, string.find, string.sub
Need to fix function interfaces and make them more uniform
b0019a1
View
7 src/luerl_basic.erl
@@ -212,9 +212,10 @@ tostring(N) when is_number(N) ->
end,
iolist_to_binary(S);
tostring(S) when is_binary(S) -> S;
-tostring(#tref{}=T) -> iolist_to_binary(io_lib:write(T));
-tostring({function,_,_,_,_}) -> iolist_to_binary(io_lib:write(function));
-tostring({function,_}) -> iolist_to_binary(io_lib:write(function));
+tostring(#tref{i=I}) -> iolist_to_binary(["table: ",io_lib:write(I)]);
+tostring({function,L,_,_,_}) ->
+ iolist_to_binary(["function: ",io_lib:write(L)]);
+tostring({function,F}) -> iolist_to_binary(["function: ",io_lib:write(F)]);
tostring(#thread{}) -> iolist_to_binary(io_lib:write(thread));
tostring(#userdata{}) -> <<"userdata">>;
tostring(_) -> <<"unknown">>.
View
48 src/luerl_scan.xrl
@@ -70,13 +70,19 @@ Rules.
\"(\\.|[^"\n])*\" :
%% Strip quotes.
Cs = string:substr(TokenChars, 2, TokenLen - 2),
- S = list_to_binary(chars(Cs)),
- {token,{'STRING',TokenLine,S}}.
+ case string_chars(Cs) of
+ {ok,S} ->
+ {token,{'STRING',TokenLine,list_to_binary(S)}};
+ error -> {error,"illegal string"}
+ end.
\'(\\.|[^'\n])*\' :
%% Strip quotes.
Cs = string:substr(TokenChars, 2, TokenLen - 2),
- S = list_to_binary(chars(Cs)),
- {token,{'STRING',TokenLine,S}}.
+ case string_chars(Cs) of
+ {ok,S} ->
+ {token,{'STRING',TokenLine,list_to_binary(S)}};
+ error -> {error,"illegal string"}
+ end.
\[\[([^]]|\][^]])*\]+\] :
%% Strip quotes.
Cs = string:substr(TokenChars, 3, TokenLen - 4),
@@ -158,18 +164,28 @@ base1([C|Cs], Base, SoFar) when C >= $A, C =< $F, C < Base + $A - 10 ->
base1([C|Cs], _Base, SoFar) -> {SoFar,[C|Cs]};
base1([], _Base, N) -> {N,[]}.
-%% chars(InputChars) -> Chars.
+%% string_chars(InputChars) -> {ok,Chars} | error.
%% Convert an input string into the corresponding string
%% characters. We know that the input string is correct.
-chars([$\\,$x,C|Cs0]) ->
- case hex_char(C) of
- true ->
- case base1([C|Cs0], 16, 0) of
- {N,[$;|Cs1]} -> [N|chars(Cs1)];
- _Other -> [escape_char($x)|chars([C|Cs0])]
+string_chars(Cs) -> catch {ok,chars(Cs)}.
+
+chars([$\\,C1|Cs0]) when C1 >= $0, C1 =< $9 -> %1-3 decimal digits
+ I1 = C1 - $0,
+ case Cs0 of
+ [C2|Cs1] when C2 >= $0, C2 =< $9 ->
+ I2 = C2 - $0,
+ case Cs1 of
+ [C3|Cs2] when C3 >= $0, C3 =< $9 ->
+ [100*I1 + 10*I2 + (C3-$0)|chars(Cs2)];
+ _ -> [10*I1 + I2|chars(Cs1)]
end;
- false -> [escape_char($x)|chars([C|Cs0])]
+ _ -> [I1|chars(Cs0)]
+ end;
+chars([$\\,$x,C1,C2|Cs]) -> %2 hex digits
+ case hex_char(C1) and hex_char(C2) of
+ true -> [hex_val(C1)*16+hex_val(C2)|chars(Cs)];
+ false -> throw(error)
end;
chars([$\\,C|Cs]) -> [escape_char(C)|chars(Cs)];
chars([C|Cs]) -> [C|chars(Cs)];
@@ -180,6 +196,10 @@ hex_char(C) when C >= $a, C =< $f -> true;
hex_char(C) when C >= $A, C =< $F -> true;
hex_char(_) -> false.
+hex_val(C) when C >= $0, C =< $9 -> C - $0;
+hex_val(C) when C >= $a, C =< $f -> C - $a + 10;
+hex_val(C) when C >= $A, C =< $F -> C - $A + 10.
+
escape_char($n) -> $\n; %\n = LF
escape_char($r) -> $\r; %\r = CR
escape_char($t) -> $\t; %\t = TAB
@@ -192,10 +212,10 @@ escape_char($d) -> $\d; %\d = DEL
escape_char(C) -> C.
long_bracket(Line, [$\n|Cs]) ->
- S = list_to_binary(chars(Cs)),
+ S = list_to_binary(Cs),
{token,{'STRING',Line,S}};
long_bracket(Line, Cs) ->
- S = list_to_binary(chars(Cs)),
+ S = list_to_binary(Cs),
{token,{'STRING',Line,S}}.
%% is_keyword(Name) -> boolean().
View
120 src/luerl_string.erl
@@ -33,11 +33,12 @@
-export([install/1]).
--export([test_gsub/3,test_do_match/3,test_pat/1]). %Test functions
+-export([test_gsub/3,test_do_match/3,test_pat/1, %Test functions
+ test_byte/3,test_find/4,test_sub/2,test_sub/3]).
-import(luerl_lib, [lua_error/1]). %Shorten this
--compile([bin_opt_info]). %For when we are optimising
+%%-compile([bin_opt_info]). %For when we are optimising
install(St0) ->
{T,St1} = luerl_eval:alloc_table(table(), St0),
@@ -65,22 +66,36 @@ table() -> %String table
{<<"upper">>,{function,fun upper/2}}
].
-byte([A], St) -> byte(A, 1, 1, St);
-byte([A1,A2], St) -> byte(A1, A2, A2, St);
-byte([A1,A2,A3|_], St) -> byte(A1, A2, A3, St);
-byte(As, _) -> lua_error({badarg,byte,As}).
-
-byte(A1, A2, A3, St) when is_binary(A1), is_number(A2), is_number(A3) ->
- F = round(A2), %First and last positions
- L = round(A3),
- if F >= 1, L >= F, L =< byte_size(A1) ->
- {binary_to_list(A1, F, L),St};
- true -> {[],St}
- end;
-byte(_, _, _, St) -> {[],St}.
+byte(As, St) ->
+ case luerl_lib:conv_list(As, [lstring,integer,integer]) of
+ [S|Is] ->
+ Bs = do_byte(S, byte_size(S), Is),
+ {Bs,St};
+ _ -> lua_error({badarg,byte,As}) %nil or []
+ end.
+
+do_byte(_, 0, _) -> [nil];
+do_byte(S, Len, []) -> do_byte(S, Len, 1, 1);
+do_byte(S, Len, [I]) -> do_byte(S, Len, I, I);
+do_byte(S, Len, [I,J]) -> do_byte(S, Len, I, J).
+
+do_byte(S, Len, I0, J0) -> %The same as for sub
+ I1 = do_sub_m(Len, I0),
+ J1 = do_sub_m(Len, J0),
+ do_byte_ij(S, Len, I1, J1).
+do_byte_ij(S, Len, I, J) when I < 1 -> do_byte_ij(S, Len, 1, J);
+do_byte_ij(S, Len, I, J) when J > Len -> do_byte_ij(S, Len, I, Len);
+do_byte_ij(_, _, I, J) when I > J -> [nil];
+do_byte_ij(S, _, I, J) ->
+ [ float(N) || N <- binary_to_list(S, I, J) ].
+
+test_byte(S, I, J) ->
+ do_byte(S, byte_size(S), I, J).
+
+char([nil], St) -> {[<<>>],St};
char(As, St) ->
- case catch list_to_binary(luerl_lib:tointegers(As)) of
+ case catch list_to_binary(luerl_lib:to_ints(As)) of
{'EXIT',_} -> lua_error({badarg,char,As});
B -> {[B],St}
end.
@@ -89,27 +104,31 @@ find([A1,A2], St) -> find([A1,A2,1.0], St);
find([A1,A2,A3], St) -> find([A1,A2,A3,nil], St);
find(As, St) ->
case luerl_lib:conv_list(As, [lstring,lstring,integer,lbool]) of
- nil -> lua_error({badarg,find,As});
- [S,P,I,Pl] -> {find(S, byte_size(S), P, I, Pl),St}
+ [S,P,I,Pl] -> {find(S, byte_size(S), P, I, Pl),St};
+ _ -> lua_error({badarg,find,As}) %nil, [_] or []
end.
+test_find(S, P, I, Pl) -> find(S, byte_size(S), P, I, Pl).
+
%% find(String, Length, Pattern, Start, Plain) -> [Return].
%% Adjust the starting index and find the string.
-find(_, L, _, I, _) when I > L -> [nil];
+find(_, L, _, I, _) when I > L+1 -> [nil];
find(S, L, P, I, Pl) when I < -L -> find(S, L, P, 1, Pl);
find(S, L, P, I, Pl) when I < 0 -> find(S, L, P, L+I+1, Pl);
find(S, L, P, 0, Pl) -> find(S, L, P, 1, Pl);
find(S, L, P, I, true) -> %Plain text search string
case binary:match(S, P, [{scope,{I-1,L-I+1}}]) of
- {Fs,Fl} -> [Fs+1,Fs+Fl];
+ {Fs,Fl} -> [float(Fs+1),float(Fs+Fl)];
nomatch -> [nil]
end;
find(S, L, P, I, false) -> %Pattern search string
case pat(binary_to_list(P)) of
{ok,{Pat,_},_} ->
- case find_loop(S, L, Pat, I) of
+ S1 = binary_part(S, I-1, L-I+1), %Start searching from I
+ case find_loop(S1, L, Pat, I) of
[{_,F,Len}|Cas] ->
+ io:format("f: ~p\n", [{F,Len,Cas}]),
[float(F),float(F+Len-1)|match_cas(Cas, S)];
[] -> [nil]
end;
@@ -117,12 +136,13 @@ find(S, L, P, I, false) -> %Pattern search string
end.
find_loop(_, L, _, I) when I > L -> [];
-find_loop(S0, L, Pat, I0) ->
- case do_match(S0, Pat, I0) of
+find_loop(S0, L, Pat, I) ->
+ io:format("fl: ~p\n", [{S0,Pat,I}]),
+ case do_match(S0, Pat, I) of
{match,Cas,_,_} -> Cas;
nomatch ->
- S1 = binary_part(S0, 1, L-I0),
- find_loop(S1, L, Pat, I0+1)
+ S1 = binary_part(S0, 1, L-I),
+ find_loop(S1, L, Pat, I+1)
end.
%% format([Format,Arg|_], State) -> {String,State}.
@@ -345,29 +365,35 @@ reverse(As, _) -> lua_error({badarg,reverse,As}).
%% sub(Args, State) -> {[Res],State}.
-sub([A1|As], St) ->
- case luerl_lib:conv_list([A1|As], [lstring,integer,integer]) of
- [S|Is] ->
+sub(As, St) ->
+ case luerl_lib:conv_list(As, [lstring,integer,integer]) of
+ [S,I|Js] ->
Len = byte_size(S),
- Sub = case Is of
- [I] -> do_sub(S, Len, I); %Just an I
- [I,J] -> do_sub(S, Len, I, J) %Both an I and a J
- end,
- {[Sub],St}
- end;
-sub(As, _) -> lua_error({badarg,sub,As}).
-
-do_sub(S, _, 0) -> S;
-do_sub(S, Len, I) when I < 1 -> do_sub(S, Len, Len+I+1, Len);
-do_sub(S, Len, I) -> do_sub(S, Len, I, Len).
-
-do_sub(S, Len, I, J) when I < 1 -> do_sub(S, Len, 1, J);
-do_sub(_, Len, _, J) when J < -Len -> <<>>;
-do_sub(S, Len, I, J) when J < 0 -> do_sub(S, Len, I, Len+J+1);
-do_sub(S, Len, I, J) when J > Len -> do_sub(S, Len, I, Len);
-do_sub(_, Len, I, _) when I > Len -> <<>>;
-do_sub(_, _, I, J) when J < I -> <<>>;
-do_sub(S, _, I, J) -> binary:part(S, I-1, J-I+1). %Zero-based, yuch!
+ Sub = do_sub(S, Len, I, Js), %Just I, or both I and J
+ {[Sub],St};
+ _ -> lua_error({badarg,sub,As}) %nil, [_] or []
+ end.
+
+test_sub(S, I) -> do_sub(S, byte_size(S), I, []).
+test_sub(S, I, J) -> do_sub(S, byte_size(S), I, [J]).
+
+do_sub(S, _, 0, []) -> S; %Special case this
+do_sub(S, Len, I, []) -> do_sub_1(S, Len, I, Len);
+do_sub(S, Len, I, [J]) -> do_sub_1(S, Len, I, J).
+
+do_sub_1(S, Len, I0, J0) ->
+ I1 = do_sub_m(Len, I0),
+ J1 = do_sub_m(Len, J0),
+ do_sub_ij(S, Len, I1, J1).
+
+do_sub_m(Len, I) when I < 0 -> Len+I+1; %Negative count from end
+do_sub_m(_, I) -> I.
+
+do_sub_ij(S, Len, I, J) when I < 1 -> do_sub_ij(S, Len, 1, J);
+do_sub_ij(S, Len, I, J) when J > Len -> do_sub_ij(S, Len, I, Len);
+do_sub_ij(_, _, I, J) when I > J -> <<>>;
+do_sub_ij(S, _, I, J) ->
+ binary:part(S, I-1, J-I+1). %Zero-based, yuch!
upper([A|_], St) when is_binary(A) ; is_number(A) ->
S = luerl_lib:to_list(A),
View
2  src/luerl_table.erl
@@ -62,8 +62,6 @@ concat(#tref{i=N}=T, A2, As, St) ->
_ -> lua_error({badarg,concat,[T,A2|As]})
end.
-concat(_, _, [I|_]) when I < 1.0 ->
- lua_error({illegal_val,concat,I});
concat(Tab, Sep, [I]) ->
Rest = skip_until(Tab, I),
Conc = concat_loop(Rest, I),

No commit comments for this range

Something went wrong with that request. Please try again.