on master help sign in
Merge branch 'fast-strings' into dev
commitea0679463f21f07ba99d2b9ab907c57fc984e108 authorEvan Czaplicki <info@elm-lang.org> dateThu 3 Oct 2013, 23:55 (13 years ago) parent3459672385f400
17 files changed+311−107
compiler/Generate/JavaScript.hs+1−2 compiler/Parse/Pattern.hs+1−5 compiler/Transform/Canonicalize.hs+1−1 compiler/Type/Constrain/Literal.hs+5−5 compiler/Type/Environment.hs+1−4 compiler/Type/Unify.hs+6−4 libraries/AutomatonV2.elm+5−4 libraries/Basics.elm−2 libraries/Date.elm−1 libraries/Http.elm−1 libraries/JavaScript.elm−1 libraries/List.elm−7 libraries/Native/JavaScript.js+4−4 libraries/Native/List.js+9−64 libraries/Native/Show.js+1−2 libraries/Native/String.js+146 libraries/String.elm+131
compiler/Generate/JavaScript.hs+1−2
@@ -57,14 +57,13 @@ internalImports name =
5757 , include "_L" "N.List"
5858 , include "_E" "N.Error"
5959 , include "_J" "N.JavaScript"
60− , varDecl "_str" (obj "_J.toString")
6160 , varDecl "$moduleName" (string name)
6261 ]
6362
6463literal lit =
6564 case lit of
6665 Chr c -> string [c]
67− Str s -> ref "_str" <| string s
66+ Str s -> string s
6867 IntNum n -> IntLit () n
6968 FloatNum n -> NumLit () n
7069 Boolean b -> BoolLit () b
compiler/Parse/Pattern.hs+1−5
@@ -23,11 +23,7 @@ basic = choice
2323 "True" -> PLiteral (Boolean True)
2424 "False" -> PLiteral (Boolean False)
2525 c : _ -> if isUpper c then PData v [] else PVar v
26− , do lit <- literal
27− return $ case lit of
28− Str s -> foldr combine (PData "[]" []) s
29− where combine h t = PData "::" [PLiteral (Chr h),t]
30− _ -> PLiteral lit
26+ , PLiteral <$> literal
3127 ]
3228
3329asPattern :: Pattern -> IParser Pattern
compiler/Transform/Canonicalize.hs+1−1
@@ -89,7 +89,7 @@ metadataModule ifaces modul =
8989
9090 pair n = (n,n)
9191 localEnv = map pair (map get1 (aliases modul) ++ map get1 (datatypes modul))
92− globalEnv = map pair $ ["_List",saveEnvName,"::","[]","Int","Float","Char","Bool"] ++
92+ globalEnv = map pair $ ["_List",saveEnvName,"::","[]","Int","Float","Char","Bool","String"] ++
9393 map (\n -> "_Tuple" ++ show n) [0..9]
9494 realImports = filter (not . List.isPrefixOf "Native." . fst) (imports modul)
9595 initialEnv = Map.fromList (concatMap canon realImports ++ localEnv ++ globalEnv)
compiler/Type/Constrain/Literal.hs+5−5
@@ -10,12 +10,12 @@ constrain env span literal tipe =
1010 do tipe' <- litType
1111 return . L span $ CEqual tipe tipe'
1212 where
13− prim name = Env.get env Env.types name
13+ prim name = return (Env.get env Env.types name)
1414
1515 litType =
1616 case literal of
1717 IntNum _ -> VarN `fmap` var (Is Number)
18− FloatNum _ -> return (prim "Float")
19− Chr _ -> return (prim "Char")
20− Str _ -> return (TermN (App1 (prim "_List") (prim "Char")))
21− Boolean _ -> return (prim "Bool")
18+ FloatNum _ -> prim "Float"
19+ Chr _ -> prim "Char"
20+ Str _ -> prim "String"
21+ Boolean _ -> prim "Bool"
compiler/Type/Environment.hs+1−4
@@ -55,7 +55,7 @@ makeTypes datatypes =
5555 builtins :: [(String,Int)]
5656 builtins = concat [ map tuple [0..9]
5757 , kind 1 ["_List"]
58− , kind 0 ["Int","Float","Char","Bool"]
58+ , kind 0 ["Int","Float","Char","String","Bool"]
5959 ]
6060
6161
@@ -143,9 +143,6 @@ instantiator env sourceType = go sourceType
143143 | "appendable" `isPrefixOf` x = Is Appendable
144144 | otherwise = Flexible
145145
146− Src.Data "String" [] ->
147− return (get env types "_List" <| get env types "Char")
148−
149146 Src.Data name ts -> do
150147 ts' <- mapM go ts
151148 case (Map.lookup name (types env), Map.lookup name (aliases env)) of
compiler/Type/Unify.hs+6−4
@@ -82,10 +82,10 @@ actuallyUnify span variable1 variable2 = do
8282
8383 comparableError str = TS.addError span (str ++ msg) variable1 variable2
8484 where msg = "Expecting something comparable such as an\n" ++
85− "Int, Float, Char, or a list or tuple of comparables."
85+ "Int, Float, Char, String, or a list or tuple of comparables."
8686
8787 unifyComparable var name
88− | name `elem` ["Int","Float","Char","comparable"] = flexAndUnify var
88+ | name `elem` ["Int","Float","Char","String","comparable"] = flexAndUnify var
8989 | otherwise = comparableError ""
9090
9191 unifyComparableStructure varSuper varFlex =
@@ -129,8 +129,10 @@ actuallyUnify span variable1 variable2 = do
129129 (Is Comparable, _, _, _) -> unifyComparableStructure variable1 variable2
130130 (_, Is Comparable, _, _) -> unifyComparableStructure variable2 variable1
131131
132− (Is Appendable, _, _, Just "Text.Text") -> flexAndUnify variable1
133− (_, Is Appendable, Just "Text.Text", _) -> flexAndUnify variable2
132+ (Is Appendable, _, _, Just ctor)
133+ | ctor `elem` ["Text.Text","String"] -> flexAndUnify variable1
134+ (_, Is Appendable, Just ctor, _)
135+ | ctor `elem` ["Text.Text","String"] -> flexAndUnify variable2
134136 (Is Appendable, _, _, _) -> unifyAppendable variable1 variable2
135137 (_, Is Appendable, _, _) -> unifyAppendable variable2 variable1
136138
libraries/AutomatonV2.elm+5−4
@@ -1,8 +1,9 @@
1−-- This library is a way to package up dynamic behavior. It makes it easier to
2−-- dynamically create dynamic components. See the [original release
3−-- notes](/blog/announce/version-0.5.0.elm) on this library to get a feel for how
4−-- it can be used.
51module AutomatonV2 where
2+{-| This library is a way to package up dynamic behavior. It makes it easier to
3+dynamically create dynamic components. See the [original release
4+notes](/blog/announce/version-0.5.0.elm) on this library to get a feel for how
5+it can be used.
6+-}
67
78import open Basics
89import Signal (lift,foldp,Signal)
libraries/Basics.elm−2
@@ -49,8 +49,6 @@ which happen to be radians.
4949
5050import Native.Basics
5151
52−type String = [Char]
53−
5452{-| Convert radians to standard Elm angles (radians). -}
5553radians : Float -> Float
5654radians t = t
libraries/Date.elm−1
@@ -12,7 +12,6 @@ issues with internationalization or locale formatting.
1212
1313-}
1414
15−import Basics (String)
1615import Native.Date
1716import Time (Time)
1817import Maybe (Maybe)
libraries/Http.elm−1
@@ -14,7 +14,6 @@ you have very strict latency requirements.
1414@docs Response
1515-}
1616
17−import open Basics
1817import open Signal
1918import Native.Http
2019
libraries/JavaScript.elm−1
@@ -17,7 +17,6 @@ integration.
1717-}
1818
1919import Native.JavaScript
20−import open Basics
2120
2221data JSNumber = JSNumber
2322data JSBool = JSBool
libraries/List.elm−7
@@ -191,13 +191,6 @@ unzip pairs =
191191 [] -> ([],[])
192192 (x,y)::ps -> let (xs,ys) = (unzip ps) in (x::xs,y::ys)
193193
194−{-| Split a list with a given seperator.
195−
196− split "," "hello,there,friend" == ["hello", "there", "friend"]
197−-}
198−split : [a] -> [a] -> [[a]]
199−split = Native.List.split
200−
201194{-| Places the given value between all of the lists in the second
202195argument and concatenates the result.
203196
libraries/Native/JavaScript.js+4−4
@@ -84,12 +84,12 @@ Elm.Native.JavaScript.make = function(elm) {
8484 }
8585
8686 return elm.Native.JavaScript.values = {
87− toFloat : id,
88− toBool : id,
8987 toInt : function(n) { return n|0; },
90− toString : List.fromArray,
88+ toFloat : function(n) { return +n; },
89+ toBool : id,
90+ toString : id,
9191 toList : List.fromArray,
92− fromString : function(s) { return List.toArray(s).join(''); },
92+ fromString : id,
9393 fromList : List.toArray,
9494 fromInt : id,
9595 fromFloat : id,
libraries/Native/List.js+9−64
@@ -241,13 +241,14 @@ Elm.Native.List.make = function(elm) {
241241 return xs;
242242 }
243243
244− function repeat(n, a) {
245− var arr = [];
246− while (n > 0) {
247− arr.push(a);
248− --n;
249− }
250− return fromArray(arr);
244+ function repeat(n, x) {
245+ var arr = [];
246+ var pattern = [x];
247+ while (n > 0) {
248+ if (n & 1) arr += pattern;
249+ n >>= 1, pattern += pattern;
250+ }
251+ return fromArray(arr);
251252 }
252253
253254 function join(sep, xss) {
@@ -263,61 +264,6 @@ Elm.Native.List.make = function(elm) {
263264 return fromArray(out);
264265 }
265266
266− function split(seperator, list) {
267− var array = toArray(list);
268− var alen = array.length;
269− if (alen === 0) {
270− // splitting an empty list is a list of lists: [[]]
271− return Cons(Nil,Nil);
272− }
273−
274− var sep = toArray(seperator);
275− var seplen = sep.length;
276− if (seplen === 0) {
277− // splitting with an empty sep is a list of all elements
278− // Same as (map (\x -> [x]) list)
279− var out = Nil;
280− for (var i = alen; i--; ) {
281− out = Cons(Cons(array[i],Nil), out);
282− }
283− return out;
284− }
285−
286− var matches = [-seplen];
287− var sepStart = sep[0];
288− var len = alen - seplen + 1;
289− for (var i = 0; i < len; ++i) {
290− if (Utils.eq(array[i], sepStart)) {
291− var match = true;
292− for (var j = seplen; --j; ) {
293− if (!Utils.eq(array[i+j], sep[j])) { match = false; break; }
294− }
295− if (match) {
296− matches.push(i);
297− i += seplen - 1;
298− }
299− }
300− }
301−
302− // shortcut in case of no matches
303− if (matches.length === 0) {
304− return Cons(list,Nil);
305− }
306−
307− var out = Nil;
308− var index = alen - 1;
309− for (var i = matches.length; i--; ) {
310− var temp = Nil;
311− var stop = matches[i] + seplen - 1;
312− for ( ; index > stop; --index ) {
313− temp = Cons(array[index], temp);
314− }
315− out = Cons(temp,out);
316− index -= seplen;
317− }
318− return out;
319− }
320−
321267 Elm.Native.List.values = {
322268 Nil:Nil,
323269 Cons:Cons,
@@ -355,8 +301,7 @@ Elm.Native.List.make = function(elm) {
355301 drop:F2(drop),
356302 repeat:F2(repeat),
357303
358− join:F2(join),
359− split:F2(split)
304+ join:F2(join)
360305 };
361306 return elm.Native.List = Elm.Native.List.values;
362307
libraries/Native/Show.js+1−2
@@ -82,7 +82,6 @@ Elm.Native.Show.make = function(elm) {
8282 if (type === 'object' && 'recv' in v) return '<signal>';
8383 return "<internal structure>";
8484 };
85− function show(v) { return NList.fromArray(toString(v)); }
8685
8786 function showChar (c) {
8887 return c === '\n' ? '\\n' :
@@ -96,5 +95,5 @@ Elm.Native.Show.make = function(elm) {
9695 c === '\\' ? '\\\\' : c;
9796 }
9897
99− return elm.Native.Show.values = { show:show };
98+ return elm.Native.Show.values = { show:toString };
10099};
libraries/Native/String.jsnew file+146
@@ -0,0 +1,146 @@
1+Elm.Native.String = {};
2+Elm.Native.String.make = function(elm) {
3+ elm.Native = elm.Native || {};
4+ elm.Native.String = elm.Native.String || {};
5+ if (elm.Native.String.values) return elm.Native.String.values;
6+ if ('values' in Elm.Native.String)
7+ return elm.Native.String.values = Elm.Native.String.values;
8+
9+ var Maybe = Elm.Maybe.make(elm);
10+ var Tuple2 = Elm.Native.Utils.make(elm).Tuple2;
11+
12+ function isEmpty(str) {
13+ return str.length === 0;
14+ }
15+ function cons(chr,str) {
16+ return chr + str;
17+ }
18+ function uncons(str) {
19+ var chr;
20+ return (chr = str[0]) ? Maybe.Just(Tuple2(chr, str.slice(1)))
21+ : Maybe.Nothing;
22+ }
23+ function map(f,str) {
24+ return str.map(f);
25+ }
26+ function filter(pred,str) {
27+ return str.filter(pred);
28+ }
29+ function reverse(str) {
30+ return str.reverse();
31+ }
32+ function foldl(f,b,str) {
33+ var len = str.length;
34+ for (var i = 0; i < len; ++i) {
35+ b = A2(f, str[i], b);
36+ }
37+ return b;
38+ }
39+ function foldr(f,b,str) {
40+ for (var i = str.length; i--; ) {
41+ b = A2(f, str[i], b);
42+ }
43+ return b;
44+ }
45+
46+ function split(sep, str) {
47+ return str.split(sep);
48+ }
49+ function join(sep, strs) {
50+ return strs.join(sep);
51+ }
52+ function repeat(n, chr) {
53+ var result = '';
54+ while (n > 0) {
55+ if (n & 1) result += chr;
56+ n >>= 1, chr += chr;
57+ }
58+ return result;
59+ }
60+ function center(n,chr,str) {
61+ var half = n - str.length / 2;
62+ return repeat(Math.ceil(half),chr) + str + repeat(half|0,chr);
63+ }
64+ function justifyLeft(n,chr,str) {
65+ return str + repeat(n - str.length, chr);
66+ }
67+ function justifyRight(n,chr,str) {
68+ return repeat(n - str.length, chr) + str;
69+ }
70+
71+ function trim(str) {
72+ return str.trim();
73+ }
74+ function trimLeft(str) {
75+ return str.trimLeft();
76+ }
77+ function trimRight(str) {
78+ return str.trimRight();
79+ }
80+
81+ function words(str) {
82+ return str.split(/\s+/g);
83+ }
84+ function unwords(str) {
85+ return str.join(' ');
86+ }
87+ function lines(str) {
88+ return str.split(/\r\n|\r|\n/g);
89+ }
90+ function unlines(str) {
91+ return str.join('\n');
92+ }
93+
94+ function toUpper(str) {
95+ return str.toUpperCase();
96+ }
97+ function toLower(str) {
98+ return str.toLowerCase();
99+ }
100+
101+ function any(pred, str) {
102+ for (var i = str.length; i--; ) {
103+ if (pred(str[i])) return true;
104+ }
105+ return false;
106+ }
107+ function all(pred, str) {
108+ for (var i = str.length; i--; ) {
109+ if (!pred(str[i])) return false;
110+ }
111+ return true;
112+ }
113+
114+ return Elm.Native.String.values = {
115+ isEmpty: isEmpty,
116+ cons: F2(cons),
117+ uncons: uncons,
118+ map: F2(map),
119+ filter: F2(filter),
120+ reverse: reverse,
121+ foldl: F3(foldl),
122+ foldr: F3(foldr),
123+
124+ split: F2(split),
125+ join: F2(join),
126+ repeat: F2(repeat),
127+ center: F3(center),
128+ justifyLeft: F3(justifyLeft),
129+ justifyRight: F3(justifyRight),
130+
131+ trim: trim,
132+ trimLeft: trimLeft,
133+ trimRight: trimRight,
134+
135+ words: words,
136+ unwords: unwords,
137+ lines: lines,
138+ unlines: unlines,
139+
140+ toUpper: toUpper,
141+ toLower: toLower,
142+
143+ any: F2(any),
144+ all: F2(all)
145+ };
146+};
libraries/String.elmnew file+131
@@ -0,0 +1,131 @@
1+module String where
2+{-| A built-in representation of String for effecient string manipulation.
3+-}
4+
5+import Native.String
6+import Maybe (Maybe)
7+
8+{-|
9+-}
10+isEmpty : String
11+isEmpty = Native.String.isEmpty
12+
13+{-|
14+-}
15+cons : Char -> String -> String
16+cons = Native.String.cons
17+
18+{-|
19+-}
20+uncons : String -> Maybe (Char, String)
21+uncons = Native.String.uncons
22+
23+{-|
24+-}
25+map : (Char -> Char) -> String -> String
26+map = Native.String.map
27+
28+{-|
29+-}
30+filter : (Char -> Bool) -> String -> String
31+filter = Native.String.filter
32+
33+{-|
34+-}
35+reverse : String -> String
36+reverse = Native.String.reverse
37+
38+{-|
39+-}
40+foldl : (Char -> b -> b) -> b -> String -> b
41+foldl = Native.String.foldl
42+
43+{-|
44+-}
45+foldr : (Char -> b -> b) -> b -> String -> b
46+foldr = Native.String.foldr
47+
48+{-|
49+-}
50+split : String -> String -> [String]
51+split = Native.String.split
52+
53+{-|
54+-}
55+join : String -> [String] -> String
56+join = Native.String.join
57+
58+{-|
59+-}
60+repeat : Int -> String -> String
61+repeat = Native.String.repeat
62+
63+{-|
64+-}
65+center : Int -> Char -> String -> String
66+center = Native.String.center
67+
68+{-|
69+-}
70+justifyLeft : Int -> Char -> String -> String
71+justifyLeft = Native.String.justifyLeft
72+
73+{-|
74+-}
75+justifyRight : Int -> Char -> String -> String
76+justifyRight = Native.String.justifyRight
77+
78+{-|
79+-}
80+trim : String -> String
81+trim = Native.String.trim
82+
83+{-|
84+-}
85+trimLeft : String -> String
86+trimLeft = Native.String.trimLeft
87+
88+{-|
89+-}
90+trimRight : String -> String
91+trimRight = Native.String.trimRight
92+
93+{-|
94+-}
95+words : String -> [String]
96+words = Native.String.words
97+
98+{-|
99+-}
100+unwords : [String] -> String
101+unwords = Native.String.unwords
102+
103+{-|
104+-}
105+lines : String -> [String]
106+lines = Native.String.lines
107+
108+{-|
109+-}
110+unlines : [String] -> String
111+unlines = Native.String.unlines
112+
113+{-|
114+-}
115+toUpper : String -> String
116+toUpper = Native.String.toUpper
117+
118+{-|
119+-}
120+toLower : String -> String
121+toLower = Native.String.toLower
122+
123+{-|
124+-}
125+any : (Char -> Bool) -> String -> Bool
126+any = Native.String.any
127+
128+{-|
129+-}
130+all : (Char -> Bool) -> String -> Bool
131+all = Native.String.all