Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
383 lines (318 sloc) 8.74 KB
from webidl`core` import Array
from webidl`core` import Boolean as NativeBoolean
from webidl`core` import Math
from webidl`core` import Number
from webidl`core` import String as NativeString
from helpertypes import IntStream, SimpleError
/**
* Type marker for functions.
*/
@•typealias('function')
class functionType<T> {}
/**
* Integer wraps a Number as an int type.
*/
@•typealias('int')
type Integer : Number {
/**
* Range returns a range of integers, starting at `start` and ending at `end`, inclusive.
*/
operator Range(start int, end int) {
return IntStream.OverRange(start, end)
}
/**
* ExclusiveRange returns an exclusive range of integers, starting at `start` and ending at `end - 1`.
*/
operator ExclusiveRange(start int, end int) {
return IntStream.OverRange(start, end - 1)
}
operator Plus(left int, right int) {
return Integer(Number(left) + Number(right))
}
operator Minus(left int, right int) {
return Integer(Number(left) - Number(right))
}
operator Times(left int, right int) {
return Integer(Number(left) * Number(right))
}
operator Div(left int, right int) {
return Float64(Number(left) / Number(right)).Floor()
}
operator Mod(left int, right int) {
return Integer(Number(left) % Number(right))
}
operator Compare(left int, right int) {
return left - right
}
operator Equals(left int, right int) {
return Boolean(Number(left) == Number(right))
}
/**
* String returns the String form of the integer.
*/
function String() string {
return String(Number(this).toString())
}
/**
* MapKey returns the key for integers in maps.
*/
property MapKey stringable {
get { return 'int::' + this.String() }
}
/**
* AsFloat returns this integer as a float.
*/
function AsFloat() float64 {
return float64(Number(this))
}
}
/**
* Float64 wraps a Number as a float type.
*/
@•typealias('float64')
type Float64 : Number {
/**
* String returns the String form of the float.
*/
function String() string {
return String(Number(this).toString())
}
operator Plus(left float64, right float64) {
return Float64(Number(left) + Number(right))
}
operator Minus(left float64, right float64) {
return Float64(Number(left) - Number(right))
}
operator Times(left float64, right float64) {
return Float64(Number(left) * Number(right))
}
operator Div(left float64, right float64) {
return Float64(Number(left) / Number(right))
}
operator Equals(left float64, right float64) {
return Boolean(Number(left) == Number(right))
}
operator Compare(left float64, right float64) {
return (left - right).Floor()
}
/**
* MapKey returns the key for floats in maps.
*/
property MapKey stringable {
get { return 'float::' + this.String() }
}
/**
* Floor returns the current float rounded down to the nearest integer.
*/
function Floor() int {
return Integer(Math.floor(Number(this)))
}
/**
* Ceil returns the current float rounded up to the nearest integer.
*/
function Ceil() int {
return Integer(Math.ceil(Number(this)))
}
/**
* Round returns the current float rounded to the nearest integer.
*/
function Round() int {
return Integer(Math.round(Number(this)))
}
}
/**
* Boolean wraps a NativeBoolean.
*/
@•typealias('bool')
type Boolean : NativeBoolean {
/**
* String returns the String form of the Boolean.
*/
function String() string {
return String(NativeBoolean(this).toString())
}
operator Equals(first bool, second bool) {
return Boolean(NativeBoolean(first) == NativeBoolean(second))
}
operator Bool(value bool) { return value }
}
/**
* formatTemplateString formats the given `pieces` and `values` into a string value.
*/
function formatTemplateString(pieces []string, values []stringable) string {
var overallPieces = Array.new()
for i in 0 .. pieces.Length - 1 {
overallPieces.push(NativeString(pieces[i]))
if i < values.Length {
overallPieces.push(NativeString(values[i].String()))
}
}
return String(overallPieces.join(NativeString('')))
}
/**
* String wraps a NativeString.
*/
@•typealias('string')
type String : NativeString {
operator Equals(first string, second string) {
return Boolean(NativeString(first) == NativeString(second))
}
operator Plus(first string, second string) {
return String(NativeString(first) + NativeString(second))
}
/**
* Stream returns a stream of all the characters in the string. Note that this *will*
* return pieces of unicode code points.
*/
function Stream() string* {
for index in 0..<this.Length {
yield this[index]
}
}
/**
* Reverse returns the contents of the string, but in reverse.
*/
function Reverse() string {
var reversed = ''
for c in this {
reversed = c + reversed
}
return reversed
}
/**
* normalizeIndex normalizes the given index to within the range of the string. Raises
* an error if the index is completely out of bounds.
*/
function normalizeIndex(index int) int {
var finalIndex = index
if finalIndex < 0 {
finalIndex = this.Length + index
}
if finalIndex >= this.Length || finalIndex < 0 {
reject SimpleError.WithMessage('Index is out of bounds')
}
return finalIndex
}
/**
* Index returns the `index`-th character in the string. Note that for unicode characters,
* this *will* index into the code point.
*/
operator Index(index int) string {
return String(NativeString(this)[this.normalizeIndex(index)])
}
/**
* Slice returns a slice of the current string. If `startindex` is not specified,
* the string will begin at index 0. If `endindex` is not specified, the string
* will end at its natural end.
*/
operator Slice(startindex int?, endindex int?) string {
var start = startindex ?? 0
var end = endindex ?? this.Length
if start < 0 {
start = start + this.Length
}
if end < 0 {
end = end + this.Length
}
if start >= end { return '' }
return String(NativeString(this).substring(Number(start), Number(end)))
}
operator Bool(value string) {
return !value.IsEmpty
}
/**
* Trim removes all whitespace from the left and right sides of the string.
*/
function Trim() string {
return String(NativeString(this).trim())
}
/**
* ToLowerCase returns the string in lowercase.
*/
function ToLowerCase() string {
return String(NativeString(this).toLowerCase())
}
/**
* ToUpperCase returns the string in uppercase.
*/
function ToUpperCase() string {
return String(NativeString(this).toUpperCase())
}
/**
* Split splits the string into a slice of strings based on a `separator`. If `limit` is specified,
* then the string will be split into a maximum of `limit` pieces.
*/
function Split(separator string, limit int?) []string {
var arr = NativeString(this).split(NativeString(separator), Number(limit ?? -1))
return slice<string>.ForArray(arr)
}
/**
* HasPrefix returns true if the string starts with the given `prefix`.
*/
function HasPrefix(prefix string) bool {
return this[0:prefix.Length] == prefix
}
/**
* HasSuffix returns true if the string ends with the given `suffix`.
*/
function HasSuffix(suffix string) bool {
return this[this.Length - suffix.Length:this.Length] == suffix
}
/**
* Contains returns true if this string contains the `otherString`. Note that this check
* is *case-sensitive*.
*/
function Contains(otherString string) bool {
index := int(NativeString(this).indexOf(&otherString))
return index >= 0
}
/**
* IndexOf returns the index of `otherString` in this string. If `startIndex` is specified,
* the search will begin at that index. Returns null if the string could not be found.
*/
function IndexOf(otherString string, startIndex int?) int? {
var normalizedIndex int? = startIndex
if startIndex is not null {
normalizedIndex = this.normalizeIndex(startIndex)
}
index := int(NativeString(this).indexOf(&otherString, &normalizedIndex))
if index < 0 {
return null
}
return index
}
/**
* LastIndexOf returns the last index of `otherString` in this string. If `startIndex` is specified,
* the search will begin at that index. Returns null if the string could not be found.
*/
function LastIndexOf(otherString string, startIndex int?) int? {
var normalizedIndex int? = startIndex
if startIndex is not null {
normalizedIndex = this.normalizeIndex(startIndex)
}
index := int(NativeString(this).lastIndexOf(&otherString, &normalizedIndex))
if index < 0 {
return null
}
return index
}
operator Contains(other string) {
return this.Contains(other)
}
function String() string { return this }
property MapKey stringable {
get { return this }
}
/**
* IsEmpty returns whether the string is empty.
*/
property IsEmpty bool {
get { return this.Length == 0 }
}
/**
* Length returns the length of the string.
*/
property Length int {
get { return Integer(NativeString(this).length) }
}
}
You can’t perform that action at this time.