Added an optional prompt parameter to readline and renamed it to readLine. Added string support in toInt

This commit is contained in:
nocturn9x 2021-02-04 12:03:10 +01:00
parent 3830b3f30c
commit 9ffff11bf9
5 changed files with 39 additions and 14 deletions

View File

@ -25,6 +25,8 @@ import types/native
import times
import math
import strformat
import parseutils
import strutils
@ -47,10 +49,17 @@ proc natPrint*(args: seq[ptr Obj]): tuple[kind: retNative, result: ptr Obj] =
# to nil
return (kind: retNative.Nil, result: nil)
proc natReadline*(args: seq[ptr Obj]): tuple[kind: retNative, result: ptr Obj] =
## Native function readline
## Reads a line from stdin and returns
## it as a string.
## it as a string, optionally writing
## a given prompt to stdout
if len(args) > 1:
return (kind: retNative.Exception, result: newTypeError(&"Function 'readLine' takes 0 to 1 arguments, got {len(args)}"))
elif not args[0].isStr():
return (kind: retNative.Exception, result: newTypeError(&"The prompt must be of type 'string', not '{args[0].typeName()}'"))
stdout.write(args[0].toStr())
return (kind: retNative.Object, result: stdin.readLine().asStr())
@ -65,7 +74,7 @@ proc natClock*(args: seq[ptr Obj]): tuple[kind: retNative, result: ptr Obj] =
result = (kind: retNative.Object, result: getTime().toUnixFloat().asFloat())
proc natRound*(args: seq[ptr Obj]): tuple[kind: retNative, result: ptr Obj] =
proc natRound*(args: seq[ptr Obj]): tuple[kind: retNative, result: ptr Obj] =
## Rounds a floating point number to a given
## precision (when precision == 0, this function drops the
## decimal part and returns an integer). Note that when
@ -94,22 +103,34 @@ proc natRound*(args: seq[ptr Obj]): tuple[kind: retNative, result: ptr Obj] =
result = (kind: retNative.Object, result: round(args[0].toFloat(), precision).asFloat())
proc natToInt*(args: seq[ptr Obj]): tuple[kind: retNative, result: ptr Obj] =
## Drops the decimal part of a float and returns an integer.
proc natToInt*(args: seq[ptr Obj]): tuple[kind: retNative, result: ptr Obj] =
## Drops the decimal part of a float and returns an integer or
## converts an integer string to an actual integer object.
## If the value is already an integer, the same object is returned
if args[0].isInt():
result = (kind: retNative.Object, result: args[0])
elif args[0].isFloat():
result = (kind: retNative.Object, result: int(args[0].toFloat()).asInt())
elif args[0].isStr():
let s = args[0].toStr()
for c in s:
if not c.isDigit():
return (kind: retNative.Exception, result: newValueError("invalid argument"))
try:
var num: int
discard parseInt(args[0].toStr(), num)
result = (kind: retNative.Object, result: num.asInt())
except ValueError:
result = (kind: retNative.Exception, result: newValueError("invalid argument"))
else:
result = (kind: retNative.Exception, result: newTypeError(&"input must be of type 'int' or 'float', not '{args[0].typeName()}'"))
result = (kind: retNative.Exception, result: newTypeError(&"input must be of type 'int', 'float' or 'string', not '{args[0].typeName()}'"))
proc natType*(args: seq[ptr Obj]): tuple[kind: retNative, result: ptr Obj] =
proc natType*(args: seq[ptr Obj]): tuple[kind: retNative, result: ptr Obj] =
## Returns the type of a given object as a string
result = (kind: retNative.Object, result: args[0].typeName().asStr())
proc natToString*(args: seq[ptr Obj]): tuple[kind: retNative, result: ptr Obj] =
proc natToString*(args: seq[ptr Obj]): tuple[kind: retNative, result: ptr Obj] =
## Returns the string representation of an object
result = (kind: retNative.Object, result: args[0].stringify().asStr())

View File

@ -59,5 +59,11 @@ proc newTypeError*(message: string): ptr JAPLException =
result.message = message
proc newValueError*(message: string): ptr JAPLException =
result = allocateObj(JAPLException, ObjectType.Exception)
result.errName = "ValueError"
result.message = message
proc stringify*(self: ptr JAPLException): string =
result = &"{self.errName}: {self.message}"
result = &"{self.errName}: {self.message}"

View File

@ -720,7 +720,7 @@ proc initStdlib*(vm: VM) =
vm.defineGlobal("toInt", newNative("toInt", natToInt, 1))
vm.defineGlobal("toString", newNative("toString", natToString, 1))
vm.defineGlobal("type", newNative("type", natType, 1))
vm.defineGlobal("readline", newNative("readline", natReadline, 0))
vm.defineGlobal("readLine", newNative("readLine", natReadline, -1))
when DEBUG_TRACE_VM and SKIP_STDLIB_INIT:
echo "DEBUG - VM: Skipping stdlib initialization"

View File

@ -3,8 +3,7 @@ var y = 0; //a global to keep track of state
//does not need closures for this to work yet
fun next(x) {
if (x == 10)
{
if (x == 0) {
y = y + 1;
x = 0;
}
@ -13,8 +12,7 @@ fun next(x) {
return x+y+1;
}
var i = 0;
for (; i != -1; i = next(i))
for (var i = 0; i != -1; i = next(i))
print(i);
// before using next
//stdout:0

View File

@ -1,3 +1,3 @@
//stdin:Hello world!
print(readline());
print(readLine());
//stdout:Hello world!