diff options
author | Louis Pilfold <louis@lpil.uk> | 2021-12-19 13:31:41 +0000 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2021-12-19 13:32:15 +0000 |
commit | 353bc1c6b8165739ca8c04d4e1b0e9e06b49a5bc (patch) | |
tree | 52446af40bf48608fcfa135ba11439ca51f8fbcd /src/gleam_stdlib.mjs | |
parent | 20bb7b6c42ec4830de286320f4dfb5756b0d5c2c (diff) | |
download | gleam_stdlib-353bc1c6b8165739ca8c04d4e1b0e9e06b49a5bc.tar.gz gleam_stdlib-353bc1c6b8165739ca8c04d4e1b0e9e06b49a5bc.zip |
Back to .js
Diffstat (limited to 'src/gleam_stdlib.mjs')
-rw-r--r-- | src/gleam_stdlib.mjs | 569 |
1 files changed, 0 insertions, 569 deletions
diff --git a/src/gleam_stdlib.mjs b/src/gleam_stdlib.mjs deleted file mode 100644 index 96fa4f1..0000000 --- a/src/gleam_stdlib.mjs +++ /dev/null @@ -1,569 +0,0 @@ -import { - BitString, - Error, - List, - Ok, - Result, - UtfCodepoint, - inspect, - stringBits, - toBitString, -} from "./gleam.js"; -import { - CompileError as RegexCompileError, - Match as RegexMatch, -} from "./gleam/regex.js"; -import { DecodeError } from "./gleam/dynamic.js"; -import { Some, None } from "./gleam/option.js"; - -const HASHCODE_CACHE = new WeakMap(); - -const Nil = undefined; - -export function identity(x) { - return x; -} - -export function parse_int(value) { - if (/^[-+]?(\d+)$/.test(value)) { - return new Ok(parseInt(value)); - } else { - return new Error(Nil); - } -} - -export function parse_float(value) { - if (/^[-+]?(\d+)\.(\d+)$/.test(value)) { - return new Ok(parseFloat(value)); - } else { - return new Error(Nil); - } -} - -export function to_string(term) { - return term.toString(); -} - -export function float_to_string(float) { - let string = float.toString(); - if (string.indexOf(".") >= 0) { - return string; - } else { - return string + ".0"; - } -} - -export function int_to_base_string(int, base) { - return int.toString(base).toUpperCase(); -} - -export function string_replace(string, target, substitute) { - return string.replaceAll(target, substitute); -} - -export function string_reverse(string) { - return [...string].reverse().join(""); -} - -export function string_length(string) { - let iterator = graphemes_iterator(string); - if (iterator) { - let i = 0; - for (let _ of iterator) { - i++; - } - return i; - } else { - return string.match(/./gu).length; - } -} - -function graphemes_iterator(string) { - if (Intl && Intl.Segmenter) { - return new Intl.Segmenter("en-gb").segment(string)[Symbol.iterator](); - } -} - -export function pop_grapheme(string) { - let first; - let iterator = graphemes_iterator(string); - if (iterator) { - first = iterator.next().value?.segment; - } else { - first = string.match(/./u)?.[0]; - } - if (first) { - return new Ok([first, string.slice(first.length)]); - } else { - return new Error(Nil); - } -} - -export function lowercase(string) { - return string.toLowerCase(); -} - -export function uppercase(string) { - return string.toUpperCase(); -} - -export function less_than(a, b) { - return a < b; -} - -export function add(a, b) { - return a + b; -} - -export function equal(a, b) { - return a === b; -} - -export function split(xs, pattern) { - return List.fromArray(xs.split(pattern)); -} - -export function join(xs) { - return xs.toArray().join(""); -} - -export function length(data) { - return data.length; -} - -export function slice_string(string, from, length) { - return string.slice(from, from + length); -} - -export function crop_string(string, substring) { - return string.substring(string.indexOf(substring)); -} - -export function index_of(haystack, needle) { - return haystack.indexOf(needle) | 0; -} - -export function starts_with(haystack, needle) { - return haystack.startsWith(needle); -} - -export function ends_with(haystack, needle) { - return haystack.endsWith(needle); -} - -export function split_once(haystack, needle) { - let index = haystack.indexOf(needle); - if (index >= 0) { - let before = haystack.slice(0, index); - let after = haystack.slice(index + needle.length); - return new Ok([before, after]); - } else { - return new Error(Nil); - } -} - -export function trim(string) { - return string.trim(); -} - -export function trim_left(string) { - return string.trimLeft(); -} - -export function trim_right(string) { - return string.trimRight(); -} - -export function bit_string_from_string(string) { - return new toBitString([stringBits(string)]); -} - -export function bit_string_concat(bit_strings) { - return toBitString(bit_strings.toArray().map((b) => b.buffer)); -} - -export function log(term) { - console.log(term); -} - -export function debug(term) { - console.log(inspect(term)); -} - -export function crash(message) { - throw new globalThis.Error(message); -} - -export function bit_string_to_string(bit_string) { - try { - let decoder = new TextDecoder("utf-8", { fatal: true }); - return new Ok(decoder.decode(bit_string.buffer)); - } catch (_error) { - return new Error(undefined); - } -} - -export function print(string) { - if (typeof process === "object") { - process.stdout.write(string); // We can write without a trailing newline - } else { - console.log(string); // We're in a browser. Newlines are mandated - } -} - -export function ceiling(float) { - return Math.ceil(float); -} - -export function floor(float) { - return Math.floor(float); -} - -export function round(float) { - return Math.round(float); -} - -export function truncate(float) { - return Math.trunc(float); -} - -export function power(base, exponent) { - return Math.pow(base, exponent); -} - -export function bit_string_slice(bits, position, length) { - let start = Math.min(position, position + length); - let end = Math.max(position, position + length); - if (start < 0 || end > bits.length) return new Error(Nil); - let buffer = new Uint8Array(bits.buffer.buffer, start, Math.abs(length)); - return new Ok(new BitString(buffer)); -} - -export function codepoint(int) { - return new UtfCodepoint(int); -} - -export function regex_check(regex, string) { - return regex.test(string); -} - -export function compile_regex(pattern, options) { - try { - let flags = "gu"; - if (options.case_insensitive) flags += "i"; - if (options.multi_line) flags += "m"; - return new Ok(new RegExp(pattern, flags)); - } catch (error) { - let number = (error.columnNumber || 0) | 0; - return new Error(new RegexCompileError(error.message, number)); - } -} - -export function regex_scan(regex, string) { - let matches = Array.from(string.matchAll(regex)).map((match) => { - let content = match.shift(); - let submatches = match.map((x) => (x ? new Some(x) : new None())); - return new RegexMatch(content, List.fromArray(submatches)); - }); - return List.fromArray(matches); -} - -class Map { - static #hashcode_cache = new WeakMap(); - - static hash(value) { - let existing = this.#hashcode_cache.get(value); - if (existing) { - return existing; - } else if (value instanceof Object) { - let hashcode = JSON.stringify(value); - HASHCODE_CACHE.set(value, hashcode); - return hashcode; - } else { - return value.toString(); - } - } - - constructor() { - this.entries = new globalThis.Map(); - } - - get size() { - return this.entries.size; - } - - inspect() { - let entries = [...this.entries.values()] - .map((pair) => inspect(pair)) - .join(", "); - return `map.from_list([${entries}])`; - } - - copy() { - let map = new Map(); - map.entries = new globalThis.Map(this.entries); - return map; - } - - toList() { - return List.fromArray([...this.entries.values()]); - } - - insert(k, v) { - let map = this.copy(); - map.entries.set(Map.hash(k), [k, v]); - return map; - } - - delete(k) { - let map = this.copy(); - map.entries.delete(Map.hash(k)); - return map; - } - - get(key) { - let code = Map.hash(key); - if (this.entries.has(code)) { - return new Ok(this.entries.get(code)[1]); - } else { - return new Error(Nil); - } - } -} - -export function new_map() { - return new Map(); -} - -export function map_size(map) { - return map.size; -} - -export function map_to_list(map) { - return map.toList(); -} - -export function map_remove(k, map) { - return map.delete(k); -} - -export function map_get(map, key) { - return map.get(key); -} - -export function map_insert(key, value, map) { - return map.insert(key, value); -} - -function unsafe_percent_decode(string) { - return decodeURIComponent((string || "").replace("+", " ")); -} - -export function percent_decode(string) { - try { - return new Ok(unsafe_percent_decode(string)); - } catch (error) { - return new Error(Nil); - } -} - -export function percent_encode(string) { - return encodeURIComponent(string); -} - -export function parse_query(query) { - try { - let pairs = []; - for (let section of query.split("&")) { - let [key, value] = section.split("="); - if (!key) continue; - pairs.push([unsafe_percent_decode(key), unsafe_percent_decode(value)]); - } - return new Ok(List.fromArray(pairs)); - } catch (error) { - return new Error(Nil); - } -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -export function encode64(bit_string) { - let aBytes = bit_string.buffer; - let nMod3 = 2, - sB64Enc = ""; - - for (let nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) { - nMod3 = nIdx % 3; - if (nIdx > 0 && ((nIdx * 4) / 3) % 76 === 0) { - sB64Enc += "\r\n"; - } - nUint24 |= aBytes[nIdx] << ((16 >>> nMod3) & 24); - if (nMod3 === 2 || aBytes.length - nIdx === 1) { - sB64Enc += String.fromCharCode( - uint6ToB64((nUint24 >>> 18) & 63), - uint6ToB64((nUint24 >>> 12) & 63), - uint6ToB64((nUint24 >>> 6) & 63), - uint6ToB64(nUint24 & 63) - ); - nUint24 = 0; - } - } - - return ( - sB64Enc.substr(0, sB64Enc.length - 2 + nMod3) + - (nMod3 === 2 ? "" : nMod3 === 1 ? "=" : "==") - ); -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -function uint6ToB64(nUint6) { - return nUint6 < 26 - ? nUint6 + 65 - : nUint6 < 52 - ? nUint6 + 71 - : nUint6 < 62 - ? nUint6 - 4 - : nUint6 === 62 - ? 43 - : nUint6 === 63 - ? 47 - : 65; -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -function b64ToUint6(nChr) { - return nChr > 64 && nChr < 91 - ? nChr - 65 - : nChr > 96 && nChr < 123 - ? nChr - 71 - : nChr > 47 && nChr < 58 - ? nChr + 4 - : nChr === 43 - ? 62 - : nChr === 47 - ? 63 - : 0; -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -export function decode64(sBase64) { - if (sBase64.match(/[^A-Za-z0-9\+\/=]/g)) return new Error(Nil); - let sB64Enc = sBase64.replace(/=/g, ""); - let nInLen = sB64Enc.length; - let nOutLen = (nInLen * 3 + 1) >> 2; - let taBytes = new Uint8Array(nOutLen); - - for ( - let nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; - nInIdx < nInLen; - nInIdx++ - ) { - nMod4 = nInIdx & 3; - nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << (6 * (3 - nMod4)); - if (nMod4 === 3 || nInLen - nInIdx === 1) { - for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) { - taBytes[nOutIdx] = (nUint24 >>> ((16 >>> nMod3) & 24)) & 255; - } - nUint24 = 0; - } - } - - return new Ok(new BitString(taBytes)); -} - -export function classify_dynamic(data) { - if (typeof data === "string") { - return "String"; - } else if (Result.isResult(data)) { - return "Result"; - } else if (List.isList(data)) { - return "List"; - } else if (Number.isInteger(data)) { - return "Int"; - } else if (Array.isArray(data)) { - return `Tuple of ${data.length} elements`; - } else if (BitString.isBitString(data)) { - return "BitString"; - } else if (data instanceof Map) { - return "Map"; - } else if (typeof data === "number") { - return "Float"; - } else { - let type = typeof data; - return type.charAt(0).toUpperCase() + type.slice(1); - } -} - -function decoder_error(expected, got) { - return new Error(new DecodeError(expected, classify_dynamic(got))); -} - -export function decode_string(data) { - return typeof data === "string" - ? new Ok(data) - : decoder_error("String", data); -} - -export function decode_int(data) { - return Number.isInteger(data) ? new Ok(data) : decoder_error("Int", data); -} - -export function decode_float(data) { - return typeof data === "number" ? new Ok(data) : decoder_error("Float", data); -} - -export function decode_bool(data) { - return typeof data === "boolean" ? new Ok(data) : decoder_error("Bool", data); -} - -export function decode_bit_string(data) { - return BitString.isBitString(data) - ? new Ok(data) - : decoder_error("BitString", data); -} - -export function decode_tuple(data) { - return Array.isArray(data) ? new Ok(data) : decoder_error("Tuple", data); -} - -export function tuple_get(data, index) { - return index >= 0 && data.length > index - ? new Ok(data[index]) - : new Error(Nil); -} - -export function decode_list(data) { - return List.isList(data) ? new Ok(data) : decoder_error("List", data); -} - -export function decode_result(data) { - return Result.isResult(data) ? new Ok(data) : decoder_error("Result", data); -} - -export function decode_map(data) { - return data instanceof Map ? new Ok(data) : decoder_error("Map", data); -} - -export function decode_option(data, decoder) { - if (data === null || data === undefined || data instanceof None) - return new Ok(new None()); - if (data instanceof Some) data = data[0]; - let result = decoder(data); - if (result.isOk()) { - return new Ok(new Some(result[0])); - } else { - return result; - } -} - -export function decode_field(value, name) { - let error = () => decoder_error(`Value with field ${inspect(name)}`, value); - if (value instanceof Map) { - let entry = value.get(name); - return entry.isOk() ? entry : error(); - } - try { - return name in value ? new Ok(value[name]) : error(); - } catch { - return error(); - } -} |