on master help sign in
Merge branch 'fast-strings' into dev
ea06794Evan Czaplicki
compiler/Generate/JavaScript.hs+1−2
@@ -57,14 +57,13 @@ internalImports name =
57 , include "_L" "N.List"
57 , include "_L" "N.List"
58 , include "_E" "N.Error"
58 , include "_E" "N.Error"
59 , include "_J" "N.JavaScript"
59 , include "_J" "N.JavaScript"
60− , varDecl "_str" (obj "_J.toString")
61 , varDecl "$moduleName" (string name)
60 , varDecl "$moduleName" (string name)
62 ]
61 ]
63
62
64literal lit =
63literal lit =
65 case lit of
64 case lit of
66 Chr c -> string [c]
65 Chr c -> string [c]
67− Str s -> ref "_str" <| string s
66+ Str s -> string s
68 IntNum n -> IntLit () n
67 IntNum n -> IntLit () n
69 FloatNum n -> NumLit () n
68 FloatNum n -> NumLit () n
70 Boolean b -> BoolLit () b
69 Boolean b -> BoolLit () b
compiler/Parse/Pattern.hs+1−5
@@ -23,11 +23,7 @@ basic = choice
23 "True" -> PLiteral (Boolean True)
23 "True" -> PLiteral (Boolean True)
24 "False" -> PLiteral (Boolean False)
24 "False" -> PLiteral (Boolean False)
25 c : _ -> if isUpper c then PData v [] else PVar v
25 c : _ -> if isUpper c then PData v [] else PVar v
26− , do lit <- literal
26+ , PLiteral <$> 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
31 ]
27 ]
32
28
33asPattern :: Pattern -> IParser Pattern
29asPattern :: Pattern -> IParser Pattern
compiler/Transform/Canonicalize.hs+1−1
@@ -89,7 +89,7 @@ metadataModule ifaces modul =
89
89
90 pair n = (n,n)
90 pair n = (n,n)
91 localEnv = map pair (map get1 (aliases modul) ++ map get1 (datatypes modul))
91 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"] ++
93 map (\n -> "_Tuple" ++ show n) [0..9]
93 map (\n -> "_Tuple" ++ show n) [0..9]
94 realImports = filter (not . List.isPrefixOf "Native." . fst) (imports modul)
94 realImports = filter (not . List.isPrefixOf "Native." . fst) (imports modul)
95 initialEnv = Map.fromList (concatMap canon realImports ++ localEnv ++ globalEnv)
95 initialEnv = Map.fromList (concatMap canon realImports ++ localEnv ++ globalEnv)
compiler/Type/Constrain/Literal.hs+5−5
@@ -10,12 +10,12 @@ constrain env span literal tipe =
10 do tipe' <- litType
10 do tipe' <- litType
11 return . L span $ CEqual tipe tipe'
11 return . L span $ CEqual tipe tipe'
12 where
12 where
13− prim name = Env.get env Env.types name
13+ prim name = return (Env.get env Env.types name)
14
14
15 litType =
15 litType =
16 case literal of
16 case literal of
17 IntNum _ -> VarN `fmap` var (Is Number)
17 IntNum _ -> VarN `fmap` var (Is Number)
18− FloatNum _ -> return (prim "Float")
18+ FloatNum _ -> prim "Float"
19− Chr _ -> return (prim "Char")
19+ Chr _ -> prim "Char"
20− Str _ -> return (TermN (App1 (prim "_List") (prim "Char")))
20+ Str _ -> prim "String"
21− Boolean _ -> return (prim "Bool")
21+ Boolean _ -> prim "Bool"
compiler/Type/Environment.hs+1−4
@@ -55,7 +55,7 @@ makeTypes datatypes =
55 builtins :: [(String,Int)]
55 builtins :: [(String,Int)]
56 builtins = concat [ map tuple [0..9]
56 builtins = concat [ map tuple [0..9]
57 , kind 1 ["_List"]
57 , kind 1 ["_List"]
58− , kind 0 ["Int","Float","Char","Bool"]
58+ , kind 0 ["Int","Float","Char","String","Bool"]
59 ]
59 ]
60
60
61
61
@@ -143,9 +143,6 @@ instantiator env sourceType = go sourceType
143 | "appendable" `isPrefixOf` x = Is Appendable
143 | "appendable" `isPrefixOf` x = Is Appendable
144 | otherwise = Flexible
144 | otherwise = Flexible
145
145
146− Src.Data "String" [] ->
147− return (get env types "_List" <| get env types "Char")
148−
149 Src.Data name ts -> do
146 Src.Data name ts -> do
150 ts' <- mapM go ts
147 ts' <- mapM go ts
151 case (Map.lookup name (types env), Map.lookup name (aliases env)) of
148 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
82
82
83 comparableError str = TS.addError span (str ++ msg) variable1 variable2
83 comparableError str = TS.addError span (str ++ msg) variable1 variable2
84 where msg = "Expecting something comparable such as an\n" ++
84 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."
86
86
87 unifyComparable var name
87 unifyComparable var name
88− | name `elem` ["Int","Float","Char","comparable"] = flexAndUnify var
88+ | name `elem` ["Int","Float","Char","String","comparable"] = flexAndUnify var
89 | otherwise = comparableError ""
89 | otherwise = comparableError ""
90
90
91 unifyComparableStructure varSuper varFlex =
91 unifyComparableStructure varSuper varFlex =
@@ -129,8 +129,10 @@ actuallyUnify span variable1 variable2 = do
129 (Is Comparable, _, _, _) -> unifyComparableStructure variable1 variable2
129 (Is Comparable, _, _, _) -> unifyComparableStructure variable1 variable2
130 (_, Is Comparable, _, _) -> unifyComparableStructure variable2 variable1
130 (_, Is Comparable, _, _) -> unifyComparableStructure variable2 variable1
131
131
132+ (Is Appendable, _, _, Just ctor)
132− (Is Appendable, _, _, Just "Text.Text") -> flexAndUnify variable1
133+ | ctor `elem` ["Text.Text","String"] -> flexAndUnify variable1
134+ (_, Is Appendable, Just ctor, _)
133− (_, Is Appendable, Just "Text.Text", _) -> flexAndUnify variable2
135+ | ctor `elem` ["Text.Text","String"] -> flexAndUnify variable2
134 (Is Appendable, _, _, _) -> unifyAppendable variable1 variable2
136 (Is Appendable, _, _, _) -> unifyAppendable variable1 variable2
135 (_, Is Appendable, _, _) -> unifyAppendable variable2 variable1
137 (_, Is Appendable, _, _) -> unifyAppendable variable2 variable1
136
138
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.
5module AutomatonV2 where
1module 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+-}
6
7
7import open Basics
8import open Basics
8import Signal (lift,foldp,Signal)
9import Signal (lift,foldp,Signal)
libraries/Basics.elm−2
@@ -49,8 +49,6 @@ which happen to be radians.
49
49
50import Native.Basics
50import Native.Basics
51
51
52−type String = [Char]
53−
54{-| Convert radians to standard Elm angles (radians). -}
52{-| Convert radians to standard Elm angles (radians). -}
55radians : Float -> Float
53radians : Float -> Float
56radians t = t
54radians t = t
libraries/Date.elm−1
@@ -12,7 +12,6 @@ issues with internationalization or locale formatting.
12
12
13-}
13-}
14
14
15−import Basics (String)
16import Native.Date
15import Native.Date
17import Time (Time)
16import Time (Time)
18import Maybe (Maybe)
17import Maybe (Maybe)
libraries/Http.elm−1
@@ -14,7 +14,6 @@ you have very strict latency requirements.
14@docs Response
14@docs Response
15-}
15-}
16
16
17−import open Basics
18import open Signal
17import open Signal
19import Native.Http
18import Native.Http
20
19
libraries/JavaScript.elm−1
@@ -17,7 +17,6 @@ integration.
17-}
17-}
18
18
19import Native.JavaScript
19import Native.JavaScript
20−import open Basics
21
20
22data JSNumber = JSNumber
21data JSNumber = JSNumber
23data JSBool = JSBool
22data JSBool = JSBool
libraries/List.elm−7
@@ -191,13 +191,6 @@ unzip pairs =
191 [] -> ([],[])
191 [] -> ([],[])
192 (x,y)::ps -> let (xs,ys) = (unzip ps) in (x::xs,y::ys)
192 (x,y)::ps -> let (xs,ys) = (unzip ps) in (x::xs,y::ys)
193
193
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−
201{-| Places the given value between all of the lists in the second
194{-| Places the given value between all of the lists in the second
202argument and concatenates the result.
195argument and concatenates the result.
203
196
libraries/Native/JavaScript.js+4−4
@@ -84,12 +84,12 @@ Elm.Native.JavaScript.make = function(elm) {
84 }
84 }
85
85
86 return elm.Native.JavaScript.values = {
86 return elm.Native.JavaScript.values = {
87− toFloat : id,
88− toBool : id,
89 toInt : function(n) { return n|0; },
87 toInt : function(n) { return n|0; },
88+ toFloat : function(n) { return +n; },
89+ toBool : id,
90− toString : List.fromArray,
90+ toString : id,
91 toList : List.fromArray,
91 toList : List.fromArray,
92− fromString : function(s) { return List.toArray(s).join(''); },
92+ fromString : id,
93 fromList : List.toArray,
93 fromList : List.toArray,
94 fromInt : id,
94 fromInt : id,
95 fromFloat : id,
95 fromFloat : id,
libraries/Native/List.js+9−64
@@ -241,13 +241,14 @@ Elm.Native.List.make = function(elm) {
241 return xs;
241 return xs;
242 }
242 }
243
243
244− function repeat(n, a) {
244+ function repeat(n, x) {
245− var arr = [];
245+ var arr = [];
246+ var pattern = [x];
246− while (n > 0) {
247+ while (n > 0) {
247− arr.push(a);
248+ if (n & 1) arr += pattern;
248− --n;
249+ n >>= 1, pattern += pattern;
249− }
250+ }
250− return fromArray(arr);
251+ return fromArray(arr);
251 }
252 }
252
253
253 function join(sep, xss) {
254 function join(sep, xss) {
@@ -263,61 +264,6 @@ Elm.Native.List.make = function(elm) {
263 return fromArray(out);
264 return fromArray(out);
264 }
265 }
265
266
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−
321 Elm.Native.List.values = {
267 Elm.Native.List.values = {
322 Nil:Nil,
268 Nil:Nil,
323 Cons:Cons,
269 Cons:Cons,
@@ -355,8 +301,7 @@ Elm.Native.List.make = function(elm) {
355 drop:F2(drop),
301 drop:F2(drop),
356 repeat:F2(repeat),
302 repeat:F2(repeat),
357
303
358− join:F2(join),
304+ join:F2(join)
359− split:F2(split)
360 };
305 };
361 return elm.Native.List = Elm.Native.List.values;
306 return elm.Native.List = Elm.Native.List.values;
362
307
libraries/Native/Show.js+1−2
@@ -82,7 +82,6 @@ Elm.Native.Show.make = function(elm) {
82 if (type === 'object' && 'recv' in v) return '<signal>';
82 if (type === 'object' && 'recv' in v) return '<signal>';
83 return "<internal structure>";
83 return "<internal structure>";
84 };
84 };
85− function show(v) { return NList.fromArray(toString(v)); }
86
85
87 function showChar (c) {
86 function showChar (c) {
88 return c === '\n' ? '\\n' :
87 return c === '\n' ? '\\n' :
@@ -96,5 +95,5 @@ Elm.Native.Show.make = function(elm) {
96 c === '\\' ? '\\\\' : c;
95 c === '\\' ? '\\\\' : c;
97 }
96 }
98
97
99− return elm.Native.Show.values = { show:show };
98+ return elm.Native.Show.values = { show:toString };
100};
99};
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