mirror of https://github.com/japl-lang/japl.git
(Re-)Added bitwise operators and strings multiplication
This commit is contained in:
parent
1b8b8d9096
commit
dba31dfba1
|
@ -17,7 +17,7 @@ import strformat
|
|||
|
||||
const MAP_LOAD_FACTOR* = 0.75 # Load factor for builtin hashmaps (TODO)
|
||||
const ARRAY_GROW_FACTOR* = 2 # How much extra memory to allocate for dynamic arrays (TODO)
|
||||
const FRAMES_MAX* = 805 # TODO: Inspect why the VM crashes if this exceeds this value
|
||||
const FRAMES_MAX* = 825 # TODO: Inspect why the VM crashes if this exceeds this value
|
||||
const JAPL_VERSION* = "0.3.0"
|
||||
const JAPL_RELEASE* = "alpha"
|
||||
const DEBUG_TRACE_VM* = false # Traces VM execution
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
import ../memory
|
||||
import strformat
|
||||
import math
|
||||
import bitops
|
||||
import strutils
|
||||
|
||||
|
||||
type
|
||||
|
@ -1039,6 +1041,16 @@ proc mul(self: ptr Integer, other: ptr Obj): ptr Obj = # This can yield a float
|
|||
result = asNan()
|
||||
of ObjectType.Infinity:
|
||||
result = cast[ptr Infinity](other)
|
||||
of ObjectType.String:
|
||||
result = cast[ptr String](other).toStr().repeat(self.toInt()).asStr()
|
||||
else:
|
||||
raise newException(NotImplementedError, &"unsupported binary operator '*' for objects of type '{self.typeName()}' and '{other.typeName()}'")
|
||||
|
||||
|
||||
proc mul(self: ptr String, other: ptr Obj): ptr Obj = # This can yield a float!
|
||||
case other.kind:
|
||||
of ObjectType.Integer:
|
||||
result = self.toStr().repeat(cast[ptr Integer](other).toInt()).asStr()
|
||||
else:
|
||||
raise newException(NotImplementedError, &"unsupported binary operator '*' for objects of type '{self.typeName()}' and '{other.typeName()}'")
|
||||
|
||||
|
@ -1077,6 +1089,8 @@ proc mul*(self, other: ptr Obj): ptr Obj =
|
|||
result = cast[ptr NotANumber](self).mul(other)
|
||||
of ObjectType.Infinity:
|
||||
result = cast[ptr Infinity](self).mul(other)
|
||||
of ObjectType.String:
|
||||
result = cast[ptr String](self).mul(other)
|
||||
else:
|
||||
raise newException(NotImplementedError, &"unsupported binary operator '*' for objects of type '{self.typeName()}' and '{other.typeName()}'")
|
||||
|
||||
|
@ -1328,28 +1342,89 @@ proc divMod*(self, other: ptr Obj): ptr Obj =
|
|||
else:
|
||||
raise newException(NotImplementedError, &"unsupported binary operator '%' for objects of type '{self.typeName()}' and '{other.typeName()}'")
|
||||
|
||||
proc binaryAnd(self, other: ptr Obj): ptr Obj =
|
||||
|
||||
proc binaryAnd(self, other: ptr Integer): ptr Integer =
|
||||
result = bitand(self.toInt(), other.toInt()).asInt()
|
||||
|
||||
|
||||
proc binaryAnd*(self, other: ptr Obj): ptr Obj =
|
||||
## Returns the result of self & other
|
||||
## or raises NotImplementedError if the operation is unsupported
|
||||
result = nil
|
||||
case self.kind:
|
||||
of ObjectType.Integer:
|
||||
result = cast[ptr Integer](self).binaryAnd(cast[ptr Integer](other))
|
||||
else:
|
||||
raise newException(NotImplementedError, &"unsupported binary operator '&' for objects of type '{self.typeName()}' and '{other.typeName()}'")
|
||||
|
||||
|
||||
proc binaryOr(self, other: ptr Obj): ptr Obj =
|
||||
proc binaryOr(self, other: ptr Integer): ptr Integer =
|
||||
result = bitor(self.toInt(), other.toInt()).asInt()
|
||||
|
||||
|
||||
proc binaryOr*(self, other: ptr Obj): ptr Obj =
|
||||
## Returns the result of self | other
|
||||
## or raises NotImplementedError if the operation is unsupported
|
||||
result = nil
|
||||
case self.kind:
|
||||
of ObjectType.Integer:
|
||||
result = cast[ptr Integer](self).binaryOr(cast[ptr Integer](other))
|
||||
else:
|
||||
raise newException(NotImplementedError, &"unsupported binary operator '|' for objects of type '{self.typeName()}' and '{other.typeName()}'")
|
||||
|
||||
|
||||
proc binaryNot(self: ptr Obj): ptr Obj =
|
||||
proc binaryNot(self: ptr Integer): ptr Integer =
|
||||
result = bitnot(self.toInt()).asInt()
|
||||
|
||||
|
||||
proc binaryNot*(self: ptr Obj): ptr Obj =
|
||||
## Returns the result of ~self
|
||||
## or raises NotImplementedError if the operation is unsupported
|
||||
result = nil
|
||||
case self.kind:
|
||||
of ObjectType.Integer:
|
||||
result = cast[ptr Integer](self).binaryNot()
|
||||
else:
|
||||
raise newException(NotImplementedError, &"unsupported unary operator '~' for object of type '{self.typeName()}'")
|
||||
|
||||
|
||||
proc binaryXor(self, other: ptr Obj): ptr Obj =
|
||||
proc binaryXor(self, other: ptr Integer): ptr Integer =
|
||||
result = bitxor(self.toInt(), other.toInt()).asInt()
|
||||
|
||||
|
||||
proc binaryXor*(self, other: ptr Obj): ptr Obj =
|
||||
## Returns the result of self ^ other
|
||||
## or raises NotImplementedError if the operation is unsupported
|
||||
result = nil
|
||||
case self.kind:
|
||||
of ObjectType.Integer:
|
||||
result = cast[ptr Integer](self).binaryXor(cast[ptr Integer](other))
|
||||
else:
|
||||
raise newException(NotImplementedError, &"unsupported binary operator '^' for object of type '{self.typeName()}'")
|
||||
|
||||
|
||||
proc binaryShr(self, other: ptr Integer): ptr Integer =
|
||||
result = (self.toInt() shr other.toInt()).asInt()
|
||||
|
||||
|
||||
proc binaryShr*(self, other: ptr Obj): ptr Obj =
|
||||
## Returns the result of self >> other
|
||||
## or raises NotImplementedError if the operation is unsupported
|
||||
case self.kind:
|
||||
of ObjectType.Integer:
|
||||
result = cast[ptr Integer](self).binaryShr(cast[ptr Integer](other))
|
||||
else:
|
||||
raise newException(NotImplementedError, &"unsupported binary operator '>>' for object of type '{self.typeName()}'")
|
||||
|
||||
|
||||
proc binaryShl(self, other: ptr Integer): ptr Integer =
|
||||
result = (self.toInt() shr other.toInt()).asInt()
|
||||
|
||||
|
||||
proc binaryShl*(self, other: ptr Obj): ptr Obj =
|
||||
## Returns the result of self << other
|
||||
## or raises NotImplementedError if the operation is unsupported
|
||||
case self.kind:
|
||||
of ObjectType.Integer:
|
||||
result = cast[ptr Integer](self).binaryShl(cast[ptr Integer](other))
|
||||
else:
|
||||
raise newException(NotImplementedError, &"unsupported binary operator '<<' for object of type '{self.typeName()}'")
|
||||
|
||||
|
||||
proc newString*(str: string): ptr String =
|
||||
|
@ -1365,7 +1440,6 @@ proc newString*(str: string): ptr String =
|
|||
|
||||
|
||||
proc asStr*(s: string): ptr String =
|
||||
|
||||
## Converts a nim string into a
|
||||
## JAPL string
|
||||
result = newString(s)
|
||||
|
|
58
src/vm.nim
58
src/vm.nim
|
@ -302,18 +302,52 @@ proc run(self: var VM, repl: bool): InterpretResult =
|
|||
except NotImplementedError:
|
||||
self.error(newTypeError(getCurrentExceptionMsg()))
|
||||
return RuntimeError
|
||||
of OpCode.Shl: # Binary left-shift
|
||||
discard
|
||||
of OpCode.Shr: # Binary right-shift
|
||||
discard
|
||||
of OpCode.Xor: # Binary xor
|
||||
discard
|
||||
of OpCode.Bor: # Binary or
|
||||
discard
|
||||
of OpCode.Bnot: # Binary not
|
||||
discard
|
||||
of OpCode.Band: # Binary and
|
||||
discard
|
||||
of OpCode.Shl: # Bitwise left-shift
|
||||
var left = self.pop()
|
||||
var right = self.pop()
|
||||
try:
|
||||
self.push(right.binaryShl(left))
|
||||
except NotImplementedError:
|
||||
self.error(newTypeError(getCurrentExceptionMsg()))
|
||||
return RuntimeError
|
||||
of OpCode.Shr: # Bitwise right-shift
|
||||
var left = self.pop()
|
||||
var right = self.pop()
|
||||
try:
|
||||
self.push(right.binaryShr(left))
|
||||
except NotImplementedError:
|
||||
self.error(newTypeError(getCurrentExceptionMsg()))
|
||||
return RuntimeError
|
||||
of OpCode.Xor: # Bitwise xor
|
||||
var left = self.pop()
|
||||
var right = self.pop()
|
||||
try:
|
||||
self.push(right.binaryXor(left))
|
||||
except NotImplementedError:
|
||||
self.error(newTypeError(getCurrentExceptionMsg()))
|
||||
return RuntimeError
|
||||
of OpCode.Bor: # Bitwise or
|
||||
var left = self.pop()
|
||||
var right = self.pop()
|
||||
try:
|
||||
self.push(right.binaryOr(left))
|
||||
except NotImplementedError:
|
||||
self.error(newTypeError(getCurrentExceptionMsg()))
|
||||
return RuntimeError
|
||||
of OpCode.Bnot: # Bitwise not
|
||||
try:
|
||||
self.push(self.pop().binaryNot())
|
||||
except NotImplementedError:
|
||||
self.error(newTypeError(getCurrentExceptionMsg()))
|
||||
return RuntimeError
|
||||
of OpCode.Band: # Bitwise and
|
||||
var left = self.pop()
|
||||
var right = self.pop()
|
||||
try:
|
||||
self.push(right.binaryAnd(left))
|
||||
except NotImplementedError:
|
||||
self.error(newTypeError(getCurrentExceptionMsg()))
|
||||
return RuntimeError
|
||||
of OpCode.Add:
|
||||
var left = self.pop()
|
||||
var right = self.pop()
|
||||
|
|
Loading…
Reference in New Issue