Added nan and inf types

This commit is contained in:
nocturn9x 2020-08-30 13:08:13 +02:00
parent cedb3bc44b
commit dd83ef32a5
3 changed files with 50 additions and 13 deletions

View File

@ -1,10 +1,10 @@
# japl
JAPL is an interpreted, dynamically-typed and minimalistic programming language
JAPL is an interpreted, dynamically-typed, garbage-collected and minimalistic programming language
# J.. what?
You may wonder what's the meaning of JAPL: well, it turns out to be an acronym
for Just Another Programming Language, but beware! Despite the name, the name is actually read like "JPL".
for __Just Another Programming Language__, but beware! Despite the name, the pronounciation is actually the same as "JPL".
## Some backstory
@ -17,17 +17,25 @@ at [this](https://craftinginterpreters.com) link, where he describes the impleme
- Possibility to delete variables with the `del` statement
- `break` statement
- `continue` statement
- multi-line comments
- Multi-line comments (`/* like this */`)
- Nested comments
- Generators (__Coming soon__)
- A decent standard library with collections, I/O utilities and such (__Work in progress__)
- Modulo division (`%`) and exponentiation (`**`)
- `OP_CONSTANT_LONG` OpCode is implemented
- Differentiation between integers and floating point numbers
- `inf`, and `nan` types
- Possibility to have more than 255 locals in scope at any given time
- String slicing, with start:end syntax as well
- All entities are actually objects (even builtins)
- Bitwise operators (AND, OR, XOR)
- Functions default and keyword arguments
- A proper import system (__Coming soon__)
- Native asynchronous (`await`/`async fun`) support (__Coming soon__)
- Multiple inheritance (__Coming Soon__)
- Bytecode optimizations such as constant folding and stack caching (__Coming Soon__)
- Arbitrary-precision arithmetic (__Coming soon__)
- Generators (__Coming soon__)
- A standard library with collections, I/O utilities, scientific modules, etc (__Coming soon__)
- Multithreading and multiprocessing support (with a global VM Lock like CPython)
Other than that, JAPL features closures, function definitions, classes, inheritance and static scoping. You can check

View File

@ -13,7 +13,7 @@ import strutils
type
ValueTypes* = enum # All possible value types (this is the VM's notion of 'type', not the end user's)
INTEGER, DOUBLE, BOOL, NIL, OBJECT, NAN, INF
INTEGER, DOUBLE, BOOL, NIL, OBJECT, NAN, INF, MINF
Value* = object
case kind*: ValueTypes
of INTEGER:
@ -22,7 +22,7 @@ type
floatValue*: float
of BOOL:
boolValue*: bool
of NIL, INF, NAN:
of NIL, INF, NAN, MINF:
discard
of OBJECT:
obj*: ptr Obj
@ -83,6 +83,8 @@ func typeName*(value: Value): string =
case value.kind:
of BOOL, NIL, DOUBLE, INTEGER, NAN, INF:
result = ($value.kind).toLowerAscii()
of MINF:
result = "inf"
of OBJECT:
case value.obj.kind:
of ObjectTypes.STRING:
@ -135,7 +137,9 @@ func stringify*(value: Value): string =
of NAN:
result = "nan"
of INF:
result = "nil"
result = "inf"
of MINF:
result = "-inf"
func isFalsey*(value: Value): bool =
@ -150,11 +154,12 @@ func isFalsey*(value: Value): bool =
result = value.toFloat() > 0.0
of NIL:
result = true
of INF:
of INF, MINF:
result = false
of NAN:
result = true
proc valuesEqual*(a: Value, b: Value): bool =
if a.kind != b.kind:
result = false
@ -178,6 +183,8 @@ proc valuesEqual*(a: Value, b: Value): bool =
result = valuesEqual(a.obj[], b.obj[])
of INF:
result = b.kind == INF
of MINF:
result = b.kind == MINF
of NAN:
result = false

View File

@ -168,19 +168,37 @@ proc run(self: var VM, debug, repl: bool): InterpretResult =
if res is bool:
self.push(Value(kind: BOOL, boolValue: bool res))
else:
self.push(Value(kind: DOUBLE, floatValue: float res))
var res = float res
if res == Inf:
self.push(Value(kind: ValueTypes.INF))
elif res == -Inf:
self.push(Value(kind: MINF))
else:
self.push(Value(kind: DOUBLE, floatValue: float res))
elif leftVal.isInt() and rightVal.isFloat():
var res = `op`(float leftVal.toInt(), rightVal.toFloat())
if res is bool:
self.push(Value(kind: BOOL, boolValue: bool res))
else:
self.push(Value(kind: DOUBLE, floatValue: float res))
var res = float res
if res == Inf:
self.push(Value(kind: ValueTypes.INF))
elif res == -Inf:
self.push(Value(kind: MINF))
else:
self.push(Value(kind: DOUBLE, floatValue: float res))
elif leftVal.isFloat() and rightVal.isFloat():
var res = `op`(leftVal.toFloat(), rightVal.toFloat())
if res is bool:
self.push(Value(kind: BOOL, boolValue: bool res))
else:
self.push(Value(kind: DOUBLE, floatValue: float res))
var res = float res
if res == Inf:
self.push(Value(kind: ValueTypes.INF))
elif res == -Inf:
self.push(Value(kind: MINF))
else:
self.push(Value(kind: DOUBLE, floatValue: float res))
else:
var tmp = `op`(leftVal.toInt(), rightVal.toInt())
if tmp is int:
@ -241,6 +259,10 @@ proc run(self: var VM, debug, repl: bool): InterpretResult =
of INTEGER:
cur.intValue = -cur.toInt()
self.push(cur)
of ValueTypes.INF:
self.push(Value(kind: MINF))
of ValueTypes.MINF:
self.push(Value(kind: ValueTypes.INF))
else:
self.error(newTypeError(&"Unsupported unary operator '-' for object of type '{cur.typeName()}'"))
of OP_ADD: