@effekt-lang/effekt 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/effekt +0 -0
- package/bin/effekt.sh +1 -1
- package/libraries/chez/common/effekt_primitives.ss +10 -2
- package/libraries/chez/common/immutable/cslist.effekt +13 -7
- package/libraries/chez/common/mutable/dict.effekt +8 -10
- package/libraries/chez/common/text/regex.effekt +7 -9
- package/libraries/common/args.effekt +95 -0
- package/libraries/common/array.effekt +225 -0
- package/libraries/common/bench.effekt +60 -0
- package/libraries/common/buffer.effekt +123 -0
- package/libraries/common/bytes.effekt +125 -0
- package/libraries/{chez/common/immutable → common}/dequeue.effekt +18 -4
- package/libraries/common/effekt.effekt +764 -0
- package/libraries/common/exception.effekt +122 -0
- package/libraries/common/io/console.effekt +66 -0
- package/libraries/common/io/error.effekt +365 -0
- package/libraries/common/io/files.effekt +282 -0
- package/libraries/common/io/network.effekt +105 -0
- package/libraries/common/io/time.effekt +15 -0
- package/libraries/common/io.effekt +158 -0
- package/libraries/{llvm/immutable → common}/list.effekt +83 -74
- package/libraries/common/option.effekt +72 -0
- package/libraries/common/process.effekt +10 -0
- package/libraries/common/queue.effekt +140 -0
- package/libraries/common/ref.effekt +63 -0
- package/libraries/common/result.effekt +45 -0
- package/libraries/{ml/immutable → common}/seq.effekt +30 -19
- package/libraries/common/string.effekt +395 -0
- package/libraries/common/test.effekt +98 -0
- package/libraries/js/effekt_builtins.js +37 -6
- package/libraries/js/io.js +143 -0
- package/libraries/js/mutable/map.effekt +8 -9
- package/libraries/js/text/regex.effekt +7 -8
- package/libraries/js/unsafe/cont.effekt +2 -2
- package/libraries/js/web/dom.effekt +13 -13
- package/libraries/llvm/array.c +53 -0
- package/libraries/llvm/buffer.c +181 -76
- package/libraries/llvm/forward-declare-c.ll +27 -8
- package/libraries/llvm/io.c +543 -1
- package/libraries/llvm/io.ll +19 -0
- package/libraries/llvm/main.c +3 -1
- package/libraries/llvm/ref.c +45 -0
- package/libraries/llvm/rts.ll +496 -354
- package/libraries/llvm/types.c +23 -0
- package/libraries/ml/effekt.sml +2 -0
- package/libraries/ml/internal/mllist.effekt +9 -0
- package/libraries/ml/internal/mloption.effekt +18 -0
- package/libraries/ml/random.effekt +9 -9
- package/libraries/ml/text/regex.effekt +14 -19
- package/licenses/eclipse public license, version 2.0 - epl-2.0.html +2 -2
- package/licenses/mit license - mit-license.html +527 -57
- package/licenses/the bsd license - bsd-license.html +530 -55
- package/licenses/the mit license - mit.html +528 -58
- package/package.json +2 -2
- package/libraries/chez/callcc/effekt.effekt +0 -221
- package/libraries/chez/common/effekt_matching.ss +0 -100
- package/libraries/chez/common/immutable/list.effekt +0 -643
- package/libraries/chez/common/immutable/option.effekt +0 -39
- package/libraries/chez/common/immutable/result.effekt +0 -29
- package/libraries/chez/common/io/args.effekt +0 -20
- package/libraries/chez/common/mutable/array.effekt +0 -27
- package/libraries/chez/common/mutable/heap.effekt +0 -12
- package/libraries/chez/common/test.effekt +0 -59
- package/libraries/chez/common/text/string.effekt +0 -46
- package/libraries/chez/lift/effekt.effekt +0 -217
- package/libraries/chez/monadic/effekt.effekt +0 -218
- package/libraries/js/effekt.effekt +0 -284
- package/libraries/js/effekt_matching.js +0 -79
- package/libraries/js/immutable/dequeue.effekt +0 -78
- package/libraries/js/immutable/list.effekt +0 -643
- package/libraries/js/immutable/option.effekt +0 -49
- package/libraries/js/immutable/result.effekt +0 -29
- package/libraries/js/io/args.effekt +0 -9
- package/libraries/js/io/async.effekt +0 -28
- package/libraries/js/io/async.js +0 -2
- package/libraries/js/io/file.effekt +0 -50
- package/libraries/js/io/file_include.js +0 -13
- package/libraries/js/mutable/array.effekt +0 -98
- package/libraries/js/mutable/heap.effekt +0 -32
- package/libraries/js/test.effekt +0 -59
- package/libraries/js/text/string.effekt +0 -64
- package/libraries/llvm/effekt.effekt +0 -243
- package/libraries/llvm/immutable/option.effekt +0 -53
- package/libraries/llvm/immutable/result.effekt +0 -29
- package/libraries/llvm/io/args.effekt +0 -24
- package/libraries/llvm/text/string.effekt +0 -179
- package/libraries/ml/effekt.effekt +0 -267
- package/libraries/ml/immutable/dequeue.effekt +0 -81
- package/libraries/ml/immutable/list.effekt +0 -674
- package/libraries/ml/immutable/option.effekt +0 -53
- package/libraries/ml/immutable/result.effekt +0 -29
- package/libraries/ml/internal/option.effekt +0 -18
- package/libraries/ml/io/args.effekt +0 -41
- package/libraries/ml/mutable/array.effekt +0 -43
- package/libraries/ml/test.effekt +0 -60
- package/libraries/ml/text/string.effekt +0 -81
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import immutable/option
|
|
2
|
-
|
|
3
|
-
// Results
|
|
4
|
-
// =======
|
|
5
|
-
// The "reification" of the Exception[E] effect.
|
|
6
|
-
type Result[A, E] {
|
|
7
|
-
Error(exception: E, msg: String);
|
|
8
|
-
Success(a: A)
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
def result[A, E] { f: () => A / Exception[E] }: Result[A, E] = try {
|
|
12
|
-
Success(f())
|
|
13
|
-
} with Exception[E] {
|
|
14
|
-
def raise(exc, msg) = Error(exc, msg)
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Extracts the value of a result, if available
|
|
19
|
-
* Monadic "reflection"
|
|
20
|
-
*/
|
|
21
|
-
def value[A, E](r: Result[A, E]): A / Exception[E] = r match {
|
|
22
|
-
case Success(a) => a
|
|
23
|
-
case Error(exc, msg) => do raise(exc, msg)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
def toOption[A, E](r: Result[A, E]): Option[A] = r match {
|
|
27
|
-
case Success(a) => Some(a)
|
|
28
|
-
case Error(exc, msg) => None()
|
|
29
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
module internal/option
|
|
2
|
-
|
|
3
|
-
import effekt
|
|
4
|
-
import immutable/option
|
|
5
|
-
|
|
6
|
-
extern type MLOption[T]
|
|
7
|
-
|
|
8
|
-
extern pure def isDefined[T](opt: MLOption[T]): Boolean =
|
|
9
|
-
"Option.isSome ${opt}"
|
|
10
|
-
|
|
11
|
-
def isEmpty[T](opt: MLOption[T]): Boolean = not(opt.isDefined())
|
|
12
|
-
|
|
13
|
-
extern pure def force[T](opt: MLOption[T]): T =
|
|
14
|
-
"Option.valOf ${opt}"
|
|
15
|
-
|
|
16
|
-
def toOption[T](opt: MLOption[T]): Option[T] = {
|
|
17
|
-
if (isDefined(opt)) Some(force(opt)) else None()
|
|
18
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
module io/args
|
|
2
|
-
|
|
3
|
-
import effekt
|
|
4
|
-
import internal/option
|
|
5
|
-
import immutable/option
|
|
6
|
-
import immutable/list
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
// ================================================
|
|
10
|
-
//
|
|
11
|
-
// Conceptual Public Functions:
|
|
12
|
-
// - commandLineArgs(): List[String]
|
|
13
|
-
//
|
|
14
|
-
// ================================================
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
// ml Ref of ml list
|
|
18
|
-
extern type Args
|
|
19
|
-
|
|
20
|
-
// Works like an iterator
|
|
21
|
-
extern io def nativeArgs(): Args =
|
|
22
|
-
"ref (CommandLine.arguments ())"
|
|
23
|
-
|
|
24
|
-
extern """
|
|
25
|
-
fun nextArgument a =
|
|
26
|
-
case !a of
|
|
27
|
-
[] => NONE |
|
|
28
|
-
x :: xs => (a := xs; SOME x);
|
|
29
|
-
"""
|
|
30
|
-
|
|
31
|
-
// consumes the next arg if present
|
|
32
|
-
extern io def nativeNext(a: Args): MLOption[String] =
|
|
33
|
-
"nextArgument ${a}"
|
|
34
|
-
|
|
35
|
-
def commandLineArgs(): List[String] = {
|
|
36
|
-
def argsToRevList(a: Args, acc: List[String]): List[String] = toOption(nativeNext(a)) match {
|
|
37
|
-
case None() => acc
|
|
38
|
-
case Some(v) => argsToRevList(a, Cons(v, acc))
|
|
39
|
-
}
|
|
40
|
-
reverse(argsToRevList(nativeArgs(), Nil()))
|
|
41
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
module mutable/array
|
|
2
|
-
|
|
3
|
-
import immutable/option
|
|
4
|
-
|
|
5
|
-
// A mutable array, backed by a sml array.
|
|
6
|
-
extern type Array[T]
|
|
7
|
-
|
|
8
|
-
extern pure def emptyArray[T](): Array[T] =
|
|
9
|
-
"Array.fromList []"
|
|
10
|
-
|
|
11
|
-
extern pure def array[T](initialSize: Int, init: T): Array[T] =
|
|
12
|
-
"Array.array (${initialSize}, ${init})"
|
|
13
|
-
|
|
14
|
-
def get[T](arr: Array[T], index: Int): Option[T] = {
|
|
15
|
-
val len = size(arr);
|
|
16
|
-
if (index < 0 || len <= index) None()
|
|
17
|
-
else Some(unsafeGet(arr, index))
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
extern pure def size[T](arr: Array[T]): Int =
|
|
21
|
-
"Array.length ${arr}"
|
|
22
|
-
|
|
23
|
-
extern pure def unsafeGet[T](arr: Array[T], index: Int): T =
|
|
24
|
-
"Array.sub (${arr}, ${index})"
|
|
25
|
-
|
|
26
|
-
def put[T](arr: Array[T], index: Int, value: T): Unit =
|
|
27
|
-
if (index < 0 || size(arr) <= index) ()
|
|
28
|
-
else unsafeput(arr, index, value)
|
|
29
|
-
|
|
30
|
-
extern io def unsafeput[T](arr: Array[T], index: Int, value: T): Unit =
|
|
31
|
-
"Array.update (${arr}, ${index}, ${value})"
|
|
32
|
-
|
|
33
|
-
def copy[T](arr: Array[T]): Array[T] =
|
|
34
|
-
get(arr, 0) match {
|
|
35
|
-
case None() => emptyArray()
|
|
36
|
-
case Some(first) =>
|
|
37
|
-
val dst = array(size(arr), first)
|
|
38
|
-
copyInto(arr, dst);
|
|
39
|
-
dst
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
extern pure def copyInto[T](src: Array[T], dst: Array[T]): Unit =
|
|
43
|
-
"Array.copy {src = ${src}, dst = ${dst}, di = 0}"
|
package/libraries/ml/test.effekt
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import text/string
|
|
2
|
-
|
|
3
|
-
interface Assertion {
|
|
4
|
-
def assert(condition: Boolean, msg: String): Unit
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
def assertTrue(condition: Boolean, msg: String) =
|
|
8
|
-
do assert(condition, msg)
|
|
9
|
-
|
|
10
|
-
def assertTrue(condition: Boolean) =
|
|
11
|
-
do assert(condition, "Assertion failed")
|
|
12
|
-
|
|
13
|
-
def assertFalse(condition: Boolean, msg: String) =
|
|
14
|
-
do assert(not(condition), msg)
|
|
15
|
-
|
|
16
|
-
def assertFalse(condition: Boolean) =
|
|
17
|
-
do assert(not(condition), "Assertion failed")
|
|
18
|
-
|
|
19
|
-
def assertEqual[A](obtained: A, expected: A, msg: String) =
|
|
20
|
-
do assert(obtained == expected, msg)
|
|
21
|
-
|
|
22
|
-
// Note: every other backend uses a generic `show` instead
|
|
23
|
-
def assertEqual[A](obtained: A, expected: A) { show : A => String } =
|
|
24
|
-
do assert(obtained == expected, "Obtained: " ++ show(obtained) ++ "\n but expected:" ++ show(expected))
|
|
25
|
-
|
|
26
|
-
interface Test {
|
|
27
|
-
def success(name: String): Unit
|
|
28
|
-
def failure(name: String, msg: String): Unit
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
def test(name: String) { body: => Unit / Assertion } =
|
|
32
|
-
try { body(); do success(name) } with Assertion {
|
|
33
|
-
def assert(condition, msg) = if (condition) resume(()) else do failure(name, msg)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
def suite(name: String) { body: => Unit / Test }: Boolean = {
|
|
37
|
-
println("Running suite: " ++ name);
|
|
38
|
-
var failed = 0
|
|
39
|
-
var passed = 0
|
|
40
|
-
|
|
41
|
-
try { body() } with Test {
|
|
42
|
-
def success(name) = {
|
|
43
|
-
passed = passed + 1
|
|
44
|
-
println(ANSI_GREEN ++ "+ " ++ name ++ "" ++ ANSI_RESET);
|
|
45
|
-
resume(())
|
|
46
|
-
}
|
|
47
|
-
def failure(name, msg) = {
|
|
48
|
-
failed = failed + 1
|
|
49
|
-
println(ANSI_RED ++ "- (FAIL) " ++ name ++ "\n " ++ msg ++ ANSI_RESET);
|
|
50
|
-
resume(())
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
if (failed > 0) {
|
|
54
|
-
println(ANSI_RED ++ "Some tests failed (" ++ passed.show ++ " passed, " ++ failed.show ++ " failed)" ++ ANSI_RESET)
|
|
55
|
-
false
|
|
56
|
-
} else {
|
|
57
|
-
println(ANSI_GREEN ++ "All tests passed (" ++ passed.show ++ " passed)" ++ ANSI_RESET)
|
|
58
|
-
true
|
|
59
|
-
}
|
|
60
|
-
}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
module text/string
|
|
2
|
-
|
|
3
|
-
import effekt
|
|
4
|
-
import immutable/option
|
|
5
|
-
import internal/option
|
|
6
|
-
|
|
7
|
-
// For more information on the sml string type:
|
|
8
|
-
// https://smlfamily.github.io/Basis/string.html#String:STR:SPEC
|
|
9
|
-
|
|
10
|
-
def charAt(str: String, index: Int): Option[String] =
|
|
11
|
-
if (index < 0 || length(str) <= index)
|
|
12
|
-
Some(unsafeCharAt(str, index))
|
|
13
|
-
else None()
|
|
14
|
-
|
|
15
|
-
extern pure def length(str: String): Int =
|
|
16
|
-
"String.size ${str}"
|
|
17
|
-
|
|
18
|
-
extern pure def startsWith(str: String, prefix: String): Boolean =
|
|
19
|
-
"String.isPrefix ${prefix} ${str}"
|
|
20
|
-
|
|
21
|
-
extern pure def endsWith(str: String, suffix: String): Boolean =
|
|
22
|
-
"String.isSuffix ${suffix} ${str}"
|
|
23
|
-
|
|
24
|
-
// extern pure def repeat(str: String, n: Int): String =
|
|
25
|
-
// "???"
|
|
26
|
-
|
|
27
|
-
def substring(str: String, from: Int, to: Int): String = {
|
|
28
|
-
def clamp(lower: Int, x: Int, upper: Int) = max(lower, min(x, upper))
|
|
29
|
-
|
|
30
|
-
val len = str.length
|
|
31
|
-
val clampedTo = clamp(0, to, len)
|
|
32
|
-
val clampedFrom = clamp(0, from, to)
|
|
33
|
-
|
|
34
|
-
val substringLength = max(0, clampedTo - clampedFrom)
|
|
35
|
-
str.unsafeSubstring(clampedFrom, substringLength)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
def substring(str: String, from: Int): String =
|
|
39
|
-
str.substring(from, str.length)
|
|
40
|
-
|
|
41
|
-
extern pure def unsafeSubstring(str: String, from: Int, len: Int): String =
|
|
42
|
-
"String.extract (${str}, ${from}, SOME ${len})"
|
|
43
|
-
|
|
44
|
-
// extern pure def split(str: String, sep: String): Array[String] =
|
|
45
|
-
// "Array.fromList (map (String.str) (String.explode str))"
|
|
46
|
-
|
|
47
|
-
// extern pure def trim(str: String): String =
|
|
48
|
-
// "???"
|
|
49
|
-
|
|
50
|
-
// also accepts sml style `~2` for unary minus along with `+2` and `-2`
|
|
51
|
-
extern pure def internalStringToInt(str: String): MLOption[Int] =
|
|
52
|
-
"Int.fromString ${str}"
|
|
53
|
-
|
|
54
|
-
def toInt(str: String): Option[Int] = toOption(internalStringToInt(str))
|
|
55
|
-
|
|
56
|
-
extern pure def unsafeCharAt(str: String, n: Int): String =
|
|
57
|
-
"String.sub (${str}, ${n})"
|
|
58
|
-
|
|
59
|
-
def indexOf(str: String, sub: String): Option[Int] = {
|
|
60
|
-
def loop(str: String, sub: String, index: Int): Int = {
|
|
61
|
-
if (index >= str.length) { -1 }
|
|
62
|
-
else if (str.substring(index).startsWith(sub)) { index }
|
|
63
|
-
else { loop(str, sub, index + 1) }
|
|
64
|
-
}
|
|
65
|
-
val index = loop(str, sub, 0)
|
|
66
|
-
if (index == -1) { None() } else { Some(index) }
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
def lastIndexOf(str: String, sub: String): Option[Int] = {
|
|
70
|
-
def loop(str: String, sub: String, index: Int): Int = {
|
|
71
|
-
if (index < 0) { -1 }
|
|
72
|
-
else if (str.substring(index).startsWith(sub)) { index }
|
|
73
|
-
else { loop(str, sub, index - 1) }
|
|
74
|
-
}
|
|
75
|
-
val index = loop(str, sub, str.length)
|
|
76
|
-
if (index == -1) { None() } else { Some(index) }
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
val ANSI_GREEN = "\u001b[32m"
|
|
80
|
-
val ANSI_RED = "\u001b[31m"
|
|
81
|
-
val ANSI_RESET = "\u001b[0m"
|