Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
# strings
# A Python FFI provider for purescript-strings
Providing FFI files for https://github.com/purescript/purescript-strings

Available mirrors:

https://github.com/purescript-python/purescript-python-ffi-index
73 changes: 73 additions & 0 deletions python-ffi/Data/String/CodePoints.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
def _unsafeCodePointAt0(fallback):
def ap(s):
return ord(s[0])

return ap


def _codePointAtImpl(fallback, just, nothing, unsafeCodePointAt0, index, s):
length = len(s)
if index < 0 or index >= length:
return nothing
else:
return just(unsafeCodePointAt0(s[index]))


def _codePointAt(fallback):
return lambda just: lambda nothing: lambda unsafeCodePointAt0: lambda index: lambda s: _codePointAtImpl(
fallback, just, nothing, unsafeCodePointAt0, index, s
)


def _codePrefixImpl(fallback, unsafeCodePointAt0, pred, s):
cpCount = 0
for x in s:
cp = unsafeCodePointAt0(x)
if not pred(cp):
return cpCount
else:
cpCount += 1
return cpCount


def _fromCodePointArray(singleton):
def ap(cps):
return "".join(map(_singleton, cps))

return ap


def _singleton(fallback):
return chr


def _take(fallback):
def ap(n):
return lambda s: s[:n]

return ap


def _toCodePointArray(fallback):
def ap(unsafeCodePointAt0):
return lambda s: list(map(unsafeCodePointAt0, s))

return ap


def _countPrefix(fallback):
def unsafeCodePointAt0_(unsafeCodePointAt0):
def pred_(pred):
def str_(s):
count = 0
for x in s:
if not pred(x):
return count
else:
count += 1

return str_

return pred_

return unsafeCodePointAt0_
121 changes: 121 additions & 0 deletions python-ffi/Data/String/CodeUnits.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
def fromCharArray(a):
return "".join(a)


def toCharArray(s):
return list(s)


def singleton(c):
return c


def _charAt(just):
def nothing_(nothing):
def i_(i):
def s_(s):
if i >= 0 and i < len(s):
return just(s[i])
else:
return nothing

return s_

return i_

return nothing_


def _toChar(just):
return lambda nothing: lambda s: just(s) if len(s) == 1 else nothing


length = len


def countPrefix(p):
def ap(s):
i = 0
while i < len(s) and p(s[i]):
i += 1
return i

return ap


def _indexOfImpl(just, nothing, x, s):
i = s.find(x)
return nothing if i == -1 else just(i)


def _indexOf(just):
return lambda nothing: lambda x: lambda s: _indexOfImpl(just, nothing, x, s)


def _indexOfPImpl(just, nothing, x, startAt, s: str):
i = s.find(x, startAt)
return nothing if i == -1 else just(i)


def _indexOfStartingAtImpl(just, nothing, x, startAt, s):
if startAt < 0 or startAt > len(s):
return nothing
i = s.find(x, startAt)
return nothing if i == -1 else just(i)


globals()[
"_indexOf'"
] = lambda just: lambda nothing: lambda x: lambda startAt: lambda s: _indexOfStartingAtImpl(
just, nothing, x, startAt, s
)


def _lastIndexOfImpl(just, nothing, x, s: str):
i = s.rfind(x)
return nothing if i == -1 else just(i)


def _lastIndexOfPImpl(just, nothing, x, startAt, s: str):
i = s.rfind(x, startAt)
return nothing if i == -1 else just(i)


def _lastIndexOf(just):
return lambda nothing: lambda x: lambda s: _lastIndexOfImpl(just, nothing, x, s)


def _lastIndexOfStartAtImpl(just, nothing, x, startAt, s):
if startAt < 0 or startAt > len(s):
return nothing
i = s.rfind(x, 0, startAt + len(x))
return nothing if i == -1 else just(i)


globals()[
"_lastIndexOf'"
] = lambda just: lambda nothing: lambda x: lambda startAt: lambda s: _lastIndexOfStartAtImpl(
just, nothing, x, startAt, s
)


def _lastIndexOfStartingAt(just):
return lambda nothing: lambda x: lambda startAt: lambda s: _lastIndexOfStartAtImpl(
just, nothing, x, startAt, s
)


def take(n: int):
return lambda s: s[: max(n, 0)]


def drop(n: int):
return lambda s: s[max(n, 0) :]


def _slice(b):
return lambda e: lambda s: s[b:e]


def splitAt(i):
return lambda s: {"before": s[: max(i, 0)], "after": s[max(i, 0) :]}
48 changes: 48 additions & 0 deletions python-ffi/Data/String/Common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
def _localeCompareImpl(lt, eq, gt, s1, s2):
# TODO: write correct localeCompare

# var result = s1.localeCompare(s2);
# return result < 0 ? lt : result > 0 ? gt : eq;
if s1 == s2:
return eq
if s1 < s2:
return lt
if s1 > s2:
return gt


def _localeCompare(lt):
return lambda eq: lambda gt: lambda s1: lambda s2: _localeCompareImpl(
lt, eq, gt, s1, s2
)


def replace(s1):
return lambda s2: lambda s3: s3.replace(s1, s2, 1)


def replaceAll(s1):
return lambda s2: lambda s3: s3.replace(s1, s2)


def split(sep):
if len(sep) == 0:
return lambda s: list(s)
else:
return lambda s: s.split(sep)


def toLower(s):
return s.lower()


def toUpper(s):
return s.upper()


def trim(s):
return s.strip()


def joinWith(s):
return lambda xs: s.join(xs)
110 changes: 110 additions & 0 deletions python-ffi/Data/String/Regex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import re


def showRegexImpl(r):
return "" + r


globals()["showRegex'"] = showRegexImpl


def regexImpl(left):
raise NotImplementedError("FFI Not implemented. Data.String.Regex.regexImpl")


# return function (right) {
# return function (s1) {
# return function (s2) {
# try {
# return right(new RegExp(s1, s2));
# } catch (e) {
# return left(e.message);
# }

globals()["regex'"] = regexImpl


def source(r):
return r["source"]


def flagsImpl(r):
return {
"multiline": r["multiline"],
"ignoreCase": r["ignoreCase"],
"global": r["global"],
"sticky": bool(r["sticky"]),
"unicode": bool(r["unicode"]),
}


globals()["flags'"] = regexImpl


def test(r):
raise NotImplementedError("FFI Not implemented. Data.String.Regex.test")


# return function (s) {
# var lastIndex = r.lastIndex;
# var result = r.test(s);
# r.lastIndex = lastIndex;
# return result;


def _matchImpl(just, nothing, r, s):
m = re.match(r, s)
if m is None:
return nothing
else:
return just(m)


_match = lambda j: lambda n: lambda r: lambda s: _matchImpl(j, n, r, s)


# return function (nothing) {
# return function (r) {
# return function (s) {
# var m = s.match(r);
# if (m == null || m.length === 0) {
# return nothing;
# } else {
# for (var i = 0; i < m.length; i++) {
# m[i] = m[i] == null ? nothing : just(m[i]);
# }
# return just(m);
# }


def replace(r):
return lambda s1: lambda s2: s2.replace(s1, 1)


def replaceBy(r):
raise NotImplementedError("FFI Not implemented. Data.String.Regex.replaceBy")


globals()["replace'"] = replaceBy

# return function (f) {
# return function (s2) {
# return s2.replace(r, function (match) {
# return f(match)(Array.prototype.splice.call(arguments, 1, arguments.length - 3));
# });


def _searchImpl(just, nothing, r, s):
m = re.search(r, s)
if m:
return just(m.start())
else:
return nothing


def _search(just):
return lambda nothing: lambda r: lambda s: _searchImpl(just, nothing, r, s)


def split(r):
return lambda s: s.split(r)
14 changes: 14 additions & 0 deletions python-ffi/Data/String/Unsafe.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
def charAt(i):
def ap(s):
if i >= 0 and i < len(s):
return s[i]

raise IndexError("Data.String.Unsafe.charAt: Invalid index.")

return ap


def char(s):
if len(s) == 1:
return s[0]
raise ValueError("Data.String.Unsafe.char: Expected string of length 1.")