mirror of https://github.com/japl-lang/japl.git
Experimental unicode support (yay) + fixed a bug with string indexing at the last element that caused an out of bounds exception
This commit is contained in:
parent
c2aa8752f4
commit
683588f693
|
@ -1,6 +1,6 @@
|
||||||
// Production build options
|
// Production build options
|
||||||
{"flags": {
|
{"flags": {
|
||||||
"gc": "none",
|
"gc": "boehm",
|
||||||
"d": "release"
|
"d": "release"
|
||||||
},
|
},
|
||||||
"override_config": true,
|
"override_config": true,
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
import strutils
|
import strutils
|
||||||
import strformat
|
import strformat
|
||||||
import tables
|
import tables
|
||||||
|
|
||||||
|
|
||||||
import meta/token
|
import meta/token
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,19 +23,21 @@ import exception
|
||||||
|
|
||||||
import strutils
|
import strutils
|
||||||
import strformat
|
import strformat
|
||||||
|
import unicode
|
||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
String* = object of Obj
|
String* = object of Obj
|
||||||
## A string object
|
## A string object
|
||||||
str*: ptr UncheckedArray[char] # TODO -> Unicode support
|
str*: ptr UncheckedArray[char]
|
||||||
|
bytelen*: int
|
||||||
len*: int
|
len*: int
|
||||||
|
|
||||||
|
|
||||||
proc toStr*(obj: ptr Obj): string =
|
proc toStr*(obj: ptr Obj): string =
|
||||||
## Converts a JAPL string into a nim string
|
## Converts a JAPL string into a nim string
|
||||||
var strObj = cast[ptr String](obj)
|
var strObj = cast[ptr String](obj)
|
||||||
for i in 0..strObj.len - 1:
|
for i in 0..strObj.bytelen:
|
||||||
result.add(strObj.str[i])
|
result.add(strObj.str[i])
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,7 +45,7 @@ proc hash*(self: ptr String): uint64 =
|
||||||
## Implements the FNV-1a hashing algorithm
|
## Implements the FNV-1a hashing algorithm
|
||||||
## for strings
|
## for strings
|
||||||
result = 2166136261u
|
result = 2166136261u
|
||||||
for i in countup(0, self.len-1):
|
for i in countup(0, self.len - 1):
|
||||||
result = result xor uint64(self.str[i])
|
result = result xor uint64(self.str[i])
|
||||||
result *= 16777619
|
result *= 16777619
|
||||||
|
|
||||||
|
@ -52,10 +54,11 @@ proc asStr*(s: string): ptr String =
|
||||||
## Converts a nim string into a
|
## Converts a nim string into a
|
||||||
## JAPL string
|
## JAPL string
|
||||||
result = allocateObj(String, ObjectType.String)
|
result = allocateObj(String, ObjectType.String)
|
||||||
result.str = allocate(UncheckedArray[char], char, len(s))
|
result.str = allocate(UncheckedArray[char], char, s.len())
|
||||||
for i in 0..len(s) - 1:
|
for i in 0..<s.len:
|
||||||
result.str[i] = s[i]
|
result.str[i] = s[i]
|
||||||
result.len = len(s)
|
result.bytelen += 1
|
||||||
|
result.len = s.runeLen()
|
||||||
if result.len > 0:
|
if result.len > 0:
|
||||||
result.hashValue = result.hash()
|
result.hashValue = result.hash()
|
||||||
else:
|
else:
|
||||||
|
@ -72,16 +75,19 @@ proc stringify*(self: ptr String): string =
|
||||||
else:
|
else:
|
||||||
result = self.toStr()
|
result = self.toStr()
|
||||||
|
|
||||||
|
|
||||||
proc typeName*(self: ptr String): string =
|
proc typeName*(self: ptr String): string =
|
||||||
return "string"
|
return "string"
|
||||||
|
|
||||||
|
|
||||||
proc eq*(self, other: ptr String): bool =
|
proc eq*(self, other: ptr String): bool =
|
||||||
if self.len != other.len:
|
if self.bytelen != other.bytelen:
|
||||||
|
return false
|
||||||
|
elif self.len != other.len:
|
||||||
return false
|
return false
|
||||||
elif self.hash != other.hash:
|
elif self.hash != other.hash:
|
||||||
return false
|
return false
|
||||||
for i in 0..self.len - 1:
|
for i in 0..<self.bytelen:
|
||||||
if self.str[i] != other.str[i]:
|
if self.str[i] != other.str[i]:
|
||||||
return false
|
return false
|
||||||
result = true
|
result = true
|
||||||
|
@ -117,15 +123,21 @@ proc getItem*(self: ptr String, other: ptr Obj): returnType =
|
||||||
else:
|
else:
|
||||||
var index: int = other.toInt()
|
var index: int = other.toInt()
|
||||||
if index < 0:
|
if index < 0:
|
||||||
index = len(str) + other.toInt()
|
index = self.len + other.toInt()
|
||||||
if index < 0: # If even now it is less than 0 then it is out of bounds
|
if index < 0: # If even now it is less than 0 then it is out of bounds
|
||||||
result.kind = returnTypes.Exception
|
result.kind = returnTypes.Exception
|
||||||
result.result = newIndexError("string index out of bounds")
|
result.result = newIndexError("string index out of bounds")
|
||||||
elif index - 1 > len(str) - 1:
|
elif index >= self.len:
|
||||||
result.kind = returnTypes.Exception
|
result.kind = returnTypes.Exception
|
||||||
result.result = newIndexError("string index out of bounds")
|
result.result = newIndexError("string index out of bounds")
|
||||||
else:
|
else:
|
||||||
result.result = asStr(&"{str[index]}")
|
var newStr = allocateObj(String, ObjectType.String)
|
||||||
|
newStr.str = allocate(UncheckedArray[char], char, str.runeAt(index).toUTF8.runeLen())
|
||||||
|
for i in countup(0, len(str.runeAt(index).toUTF8()) - 1):
|
||||||
|
newStr.str[i] = self.str[i]
|
||||||
|
newStr.bytelen += 1
|
||||||
|
newStr.len = str.runeAt(index).toUTF8.runeLen()
|
||||||
|
result.result = newStr
|
||||||
|
|
||||||
|
|
||||||
proc Slice*(self: ptr String, a: ptr Obj, b: ptr Obj): returnType =
|
proc Slice*(self: ptr String, a: ptr Obj, b: ptr Obj): returnType =
|
||||||
|
@ -147,7 +159,7 @@ proc Slice*(self: ptr String, a: ptr Obj, b: ptr Obj): returnType =
|
||||||
startIndex = (self.len + startIndex)
|
startIndex = (self.len + startIndex)
|
||||||
if startIndex < 0:
|
if startIndex < 0:
|
||||||
startIndex = (self.len + endIndex)
|
startIndex = (self.len + endIndex)
|
||||||
elif startIndex > self.str.high():
|
elif startIndex >= self.str.high():
|
||||||
result.result = asStr("")
|
result.result = asStr("")
|
||||||
return result
|
return result
|
||||||
if endIndex > self.str.high():
|
if endIndex > self.str.high():
|
||||||
|
@ -155,4 +167,10 @@ proc Slice*(self: ptr String, a: ptr Obj, b: ptr Obj): returnType =
|
||||||
if startIndex > endIndex:
|
if startIndex > endIndex:
|
||||||
result.result = asStr("")
|
result.result = asStr("")
|
||||||
return result
|
return result
|
||||||
result.result = self.toStr()[startIndex..<endIndex].asStr()
|
var newStr = allocateObj(String, ObjectType.String)
|
||||||
|
newStr.str = allocate(UncheckedArray[char], char, self.toStr().toRunes[startIndex..<endIndex].len())
|
||||||
|
for i in countup(startIndex, endIndex - 1):
|
||||||
|
newStr.str[i] = self.str[i]
|
||||||
|
newStr.bytelen += 1
|
||||||
|
newStr.len = newStr.toStr().runeLen()
|
||||||
|
result.result = newStr
|
||||||
|
|
Loading…
Reference in New Issue