Merge branch 'devel' into nintendo_switch_support

This commit is contained in:
Joey Yakimowich-Payne 2018-06-24 14:22:43 +09:00
commit c137097e9c
33 changed files with 1722 additions and 142 deletions

View file

@ -32,7 +32,7 @@ const
## can be captured. More subpatterns cannot be captured!
type
PegKind = enum
PegKind* = enum
pkEmpty,
pkAny, ## any character (.)
pkAnyRune, ## any Unicode character (_)
@ -67,7 +67,7 @@ type
pkRule, ## a <- b
pkList, ## a, b
pkStartAnchor ## ^ --> Internal DSL: startAnchor()
NonTerminalFlag = enum
NonTerminalFlag* = enum
ntDeclared, ntUsed
NonTerminalObj = object ## represents a non terminal symbol
name: string ## the name of the symbol
@ -86,6 +86,25 @@ type
else: sons: seq[Peg]
NonTerminal* = ref NonTerminalObj
proc name*(nt: NonTerminal): string = nt.name
proc line*(nt: NonTerminal): int = nt.line
proc col*(nt: NonTerminal): int = nt.col
proc flags*(nt: NonTerminal): set[NonTerminalFlag] = nt.flags
proc rule*(nt: NonTerminal): Peg = nt.rule
proc kind*(p: Peg): PegKind = p.kind
proc term*(p: Peg): string = p.term
proc ch*(p: Peg): char = p.ch
proc charChoice*(p: Peg): ref set[char] = p.charChoice
proc nt*(p: Peg): NonTerminal = p.nt
proc index*(p: Peg): range[0..MaxSubpatterns] = p.index
iterator items*(p: Peg): Peg {.inline.} =
for s in p.sons:
yield s
iterator pairs*(p: Peg): (int, Peg) {.inline.} =
for i in 0 ..< p.sons.len:
yield (i, p.sons[i])
proc term*(t: string): Peg {.nosideEffect, rtl, extern: "npegs$1Str".} =
## constructs a PEG from a terminal string
if t.len != 1:

View file

@ -17,6 +17,10 @@ import parseutils
from math import pow, round, floor, log10
from algorithm import reverse
when defined(nimVmExportFixed):
from unicode import toLower, toUpper
export toLower, toUpper
{.deadCodeElim: on.} # dce option deprecated
{.push debugger:off .} # the user does not want to trace a part

View file

@ -692,8 +692,8 @@ template styledEchoProcessArg(f: File, cmd: TerminalCmd) =
when cmd == bgColor:
fgSetColor = false
macro styledWriteLine*(f: File, m: varargs[typed]): untyped =
## Similar to ``writeLine``, but treating terminal style arguments specially.
macro styledWrite*(f: File, m: varargs[typed]): untyped =
## Similar to ``write``, but treating terminal style arguments specially.
## When some argument is ``Style``, ``set[Style]``, ``ForegroundColor``,
## ``BackgroundColor`` or ``TerminalCmd`` then it is not sent directly to
## ``f``, but instead corresponding terminal style proc is called.
@ -702,8 +702,8 @@ macro styledWriteLine*(f: File, m: varargs[typed]): untyped =
##
## .. code-block:: nim
##
## proc error(msg: string) =
## styledWriteLine(stderr, fgRed, "Error: ", resetStyle, msg)
## stdout.styledWrite(fgRed, "red text ")
## stdout.styledWrite(fgGreen, "green text")
##
let m = callsite()
var reset = false
@ -714,8 +714,8 @@ macro styledWriteLine*(f: File, m: varargs[typed]): untyped =
case item.kind
of nnkStrLit..nnkTripleStrLit:
if i == m.len - 1:
# optimize if string literal is last, just call writeLine
result.add(newCall(bindSym"writeLine", f, item))
# optimize if string literal is last, just call write
result.add(newCall(bindSym"write", f, item))
if reset: result.add(newCall(bindSym"resetAttributes", f))
return
else:
@ -724,16 +724,24 @@ macro styledWriteLine*(f: File, m: varargs[typed]): untyped =
else:
result.add(newCall(bindSym"styledEchoProcessArg", f, item))
reset = true
result.add(newCall(bindSym"write", f, newStrLitNode("\n")))
if reset: result.add(newCall(bindSym"resetAttributes", f))
macro styledEcho*(args: varargs[untyped]): untyped =
template styledWriteLine*(f: File, args: varargs[untyped]) =
## Calls ``styledWrite`` and appends a newline at the end.
##
## Example:
##
## .. code-block:: nim
##
## proc error(msg: string) =
## styledWriteLine(stderr, fgRed, "Error: ", resetStyle, msg)
##
styledWrite(f, args)
write(f, "\n")
template styledEcho*(args: varargs[untyped]) =
## Echoes styles arguments to stdout using ``styledWriteLine``.
result = newCall(bindSym"styledWriteLine")
result.add(bindSym"stdout")
for arg in children(args):
result.add(arg)
stdout.styledWriteLine(args)
proc getch*(): char =
## Read a single character from the terminal, blocking until it is entered.
@ -781,7 +789,7 @@ when defined(windows):
inc i, x
password.string.setLen(max(password.len - x, 0))
of chr(0x0):
# modifier key - ignore - for details see
# modifier key - ignore - for details see
# https://github.com/nim-lang/Nim/issues/7764
continue
else:
@ -840,17 +848,6 @@ proc resetAttributes*() {.noconv.} =
## ``system.addQuitProc(resetAttributes)``.
resetAttributes(stdout)
when not defined(testing) and isMainModule:
#system.addQuitProc(resetAttributes)
write(stdout, "never mind")
stdout.eraseLine()
stdout.styledWriteLine("styled text ", {styleBright, styleBlink, styleUnderscore})
stdout.styledWriteLine("italic text ", {styleItalic})
stdout.setBackGroundColor(bgCyan, true)
stdout.setForeGroundColor(fgBlue)
stdout.writeLine("ordinary text")
stdout.resetAttributes()
proc isTrueColorSupported*(): bool =
## Returns true if a terminal supports true color.
return trueColorIsSupported
@ -901,3 +898,40 @@ proc disableTrueColors*() =
trueColorIsEnabled = false
else:
trueColorIsEnabled = false
when not defined(testing) and isMainModule:
#system.addQuitProc(resetAttributes)
write(stdout, "never mind")
stdout.eraseLine()
stdout.styledWriteLine({styleBright, styleBlink, styleUnderscore}, "styled text ")
stdout.styledWriteLine("italic text ", {styleItalic})
stdout.setBackGroundColor(bgCyan, true)
stdout.setForeGroundColor(fgBlue)
stdout.write("blue text in cyan background")
stdout.resetAttributes()
echo ""
stdout.writeLine("ordinary text")
echo "more ordinary text"
styledEcho styleBright, fgGreen, "[PASS]", resetStyle, fgGreen, " Yay!"
echo "ordinary text again"
styledEcho styleBright, fgRed, "[FAIL]", resetStyle, fgRed, " Nay :("
echo "ordinary text again"
setForeGroundColor(fgGreen)
echo "green text"
echo "more green text"
setForeGroundColor(fgBlue)
echo "blue text"
resetAttributes()
echo "ordinary text"
stdout.styledWriteLine(fgRed, "red text ")
stdout.styledWriteLine(fgWhite, bgRed, "white text in red background")
stdout.styledWriteLine(" ordinary text ")
stdout.styledWriteLine(fgGreen, "green text")
stdout.styledWrite(fgRed, "red text ")
stdout.styledWrite(fgWhite, bgRed, "white text in red background")
stdout.styledWrite(" ordinary text ")
stdout.styledWrite(fgGreen, "green text")
echo ""
echo "ordinary text"

View file

@ -238,11 +238,11 @@ proc utcZoneInfoFromUtc(time: Time): ZonedTime {.tags: [], raises: [], benign .}
proc utcZoneInfoFromTz(adjTime: Time): ZonedTime {.tags: [], raises: [], benign .}
proc localZoneInfoFromUtc(time: Time): ZonedTime {.tags: [], raises: [], benign .}
proc localZoneInfoFromTz(adjTime: Time): ZonedTime {.tags: [], raises: [], benign .}
proc initTime*(unix: int64, nanosecond: NanosecondRange): Time
proc initTime*(unix: int64, nanosecond: NanosecondRange): Time
{.tags: [], raises: [], benign noSideEffect.}
proc initDuration*(nanoseconds, microseconds, milliseconds,
seconds, minutes, hours, days, weeks: int64 = 0): Duration
seconds, minutes, hours, days, weeks: int64 = 0): Duration
{.tags: [], raises: [], benign noSideEffect.}
proc nanosecond*(time: Time): NanosecondRange =
@ -531,7 +531,7 @@ proc `$`*(dur: Duration): string =
let quantity = numParts[unit]
if quantity != 0.int64:
parts.add(stringifyUnit(quantity, $unit))
result = humanizeParts(parts)
proc `+`*(a, b: Duration): Duration {.operator.} =
@ -1243,23 +1243,23 @@ proc evaluateStaticInterval(interval: TimeInterval): Duration =
minutes = interval.minutes,
hours = interval.hours)
proc between*(startDt, endDt:DateTime): TimeInterval =
proc between*(startDt, endDt: DateTime): TimeInterval =
## Evaluate difference between two dates in ``TimeInterval`` format, so, it
## will be relative.
##
## **Warning:** It's not recommended to use ``between`` for ``DateTime's`` in
## different ``TimeZone's``.
## **Warning:** It's not recommended to use ``between`` for ``DateTime's`` in
## different ``TimeZone's``.
## ``a + between(a, b) == b`` is only guaranteed when ``a`` and ``b`` are in UTC.
runnableExamples:
var a = initDateTime(year = 2018, month = Month(3), monthday = 25,
var a = initDateTime(year = 2018, month = Month(3), monthday = 25,
hour = 0, minute = 59, second = 59, nanosecond = 1,
zone = utc()).local
var b = initDateTime(year = 2018, month = Month(3), monthday = 25,
var b = initDateTime(year = 2018, month = Month(3), monthday = 25,
hour = 1, minute = 1, second = 1, nanosecond = 0,
zone = utc()).local
doAssert between(a, b) == initTimeInterval(
nanoseconds=999, milliseconds=999, microseconds=999, seconds=1, minutes=1)
a = parse("2018-01-09T00:00:00+00:00", "yyyy-MM-dd'T'HH:mm:sszzz", utc())
b = parse("2018-01-10T23:00:00-02:00", "yyyy-MM-dd'T'HH:mm:sszzz")
doAssert between(a, b) == initTimeInterval(hours=1, days=2)
@ -1526,7 +1526,6 @@ proc formatToken(dt: DateTime, token: string, buf: var string) =
else:
raise newException(ValueError, "Invalid format string: " & token)
proc format*(dt: DateTime, f: string): string {.tags: [].}=
## This procedure formats `dt` as specified by `f`. The following format
## specifiers are available:
@ -1601,18 +1600,14 @@ proc format*(dt: DateTime, f: string): string {.tags: [].}=
inc(i)
formatToken(dt, currentF, result)
proc format*(time: Time, f: string, zone_info: proc(t: Time): DateTime): string {.tags: [].} =
## converts a `Time` value to a string representation. It will use format from
proc format*(time: Time, f: string, zone: Timezone = local()): string {.tags: [].} =
## Converts a `Time` value to a string representation. It will use format from
## ``format(dt: DateTime, f: string)``.
runnableExamples:
var dt = initDateTime(01, mJan, 1970, 00, 00, 00, local())
var dt = initDateTime(01, mJan, 1970, 00, 00, 00, utc())
var tm = dt.toTime()
doAssert format(tm, "yyyy-MM-dd'T'HH:mm:ss", local) == "1970-01-01T00:00:00"
dt = initDateTime(01, mJan, 1970, 00, 00, 00, utc())
tm = dt.toTime()
doAssert format(tm, "yyyy-MM-dd'T'HH:mm:ss", utc) == "1970-01-01T00:00:00"
zone_info(time).format(f)
doAssert format(tm, "yyyy-MM-dd'T'HH:mm:ss", utc()) == "1970-01-01T00:00:00"
time.inZone(zone).format(f)
proc `$`*(dt: DateTime): string {.tags: [], raises: [], benign.} =
## Converts a `DateTime` object to a string representation.
@ -1984,16 +1979,12 @@ proc countYearsAndDays*(daySpan: int): tuple[years: int, days: int] =
proc toTimeInterval*(time: Time): TimeInterval =
## Converts a Time to a TimeInterval.
##
## To be used when diffing times.
## To be used when diffing times. Consider using `between` instead.
runnableExamples:
let a = fromUnix(10)
let dt = initDateTime(01, mJan, 1970, 00, 00, 00, local())
doAssert a.toTimeInterval() == initTimeInterval(
years=1970, days=1, seconds=10, hours=convert(
Seconds, Hours, -dt.utcOffset
)
)
let b = fromUnix(1_500_000_000)
let ti = b.toTimeInterval() - a.toTimeInterval()
doAssert a + ti == b
var dt = time.local
initTimeInterval(dt.nanosecond, 0, 0, dt.second, dt.minute, dt.hour,
dt.monthday, 0, dt.month.ord - 1, dt.year)
@ -2150,7 +2141,7 @@ proc timeToTimeInterval*(t: Time): TimeInterval {.deprecated.} =
t.toTimeInterval()
proc getDayOfWeek*(day, month, year: int): WeekDay {.tags: [], raises: [], benign, deprecated.} =
## **Deprecated since v0.18.0:** use
## **Deprecated since v0.18.0:** use
## ``getDayOfWeek(monthday: MonthdayRange; month: Month; year: int)`` instead.
getDayOfWeek(day, month.Month, year)