Merge branch 'devel' of https://github.com/Araq/Nimrod into devel

This commit is contained in:
Araq
2014-08-17 21:24:01 +02:00
8 changed files with 89 additions and 555 deletions

View File

@@ -833,8 +833,8 @@ proc genSwap(p: PProc, n: PNode) =
"local $1 = $2; $2 = $3; $3 = $1;$n", [
tmp, a.address, b.address])
tmp = tmp2
appf(p.body, "var $1 = $2; $2 = $3; $3 = $1" |
"local $1 = $2; $2 = $3; $3 = $1", [tmp, a.res, b.res])
appf(p.body, "var $1 = $2; $2 = $3; $3 = $1;" |
"local $1 = $2; $2 = $3; $3 = $1;", [tmp, a.res, b.res])
proc getFieldPosition(f: PNode): int =
case f.kind
@@ -881,14 +881,15 @@ proc genArrayAddr(p: PProc, n: PNode, r: var TCompRes) =
a, b: TCompRes
first: BiggestInt
r.typ = etyBaseIndex
gen(p, n.sons[0], a)
gen(p, n.sons[1], b)
let m = if n.kind == nkHiddenAddr: n.sons[0] else: n
gen(p, m.sons[0], a)
gen(p, m.sons[1], b)
internalAssert a.typ != etyBaseIndex and b.typ != etyBaseIndex
r.address = a.res
var typ = skipTypes(n.sons[0].typ, abstractPtrs)
var typ = skipTypes(m.sons[0].typ, abstractPtrs)
if typ.kind in {tyArray, tyArrayConstr}: first = firstOrd(typ.sons[0])
else: first = 0
if optBoundsCheck in p.options and not isConstExpr(n.sons[1]):
if optBoundsCheck in p.options and not isConstExpr(m.sons[1]):
useMagic(p, "chckIndx")
r.res = ropef("chckIndx($1, $2, $3.length)-$2",
[b.res, toRope(first), a.res])
@@ -1351,7 +1352,7 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
of mEcho: genEcho(p, n, r)
of mSlurp, mStaticExec:
localError(n.info, errXMustBeCompileTime, n.sons[0].sym.name.s)
of mCopyStr: binaryExpr(p, n, r, "", "($1.slice($2,-1))")
of mCopyStr: binaryExpr(p, n, r, "", "($1.slice($2))")
of mCopyStrLast: ternaryExpr(p, n, r, "", "($1.slice($2, ($3)+1).concat(0))")
of mNewString: unaryExpr(p, n, r, "mnewString", "mnewString($1)")
of mNewStringOfCap: unaryExpr(p, n, r, "mnewString", "mnewString(0)")

View File

@@ -81,6 +81,8 @@ proc notFoundError*(c: PContext, n: PNode, errors: seq[string]) =
if c.inCompilesContext > 0:
# fail fast:
globalError(n.info, errTypeMismatch, "")
if errors.len == 0:
localError(n.info, errExprXCannotBeCalled, n[0].renderTree)
var result = msgKindToString(errTypeMismatch)
add(result, describeArgs(c, n, 1))
add(result, ')')

View File

@@ -1,503 +0,0 @@
#
#
# Nimrod's Runtime Library
# (c) Copyright 2012 Dominik Picheta
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## This module implements an asynchronous IRC client.
##
## Currently this module requires at least some knowledge of the IRC protocol.
## It provides a function for sending raw messages to the IRC server, together
## with some basic functions like sending a message to a channel.
## It automizes the process of keeping the connection alive, so you don't
## need to reply to PING messages. In fact, the server is also PING'ed to check
## the amount of lag.
##
## .. code-block:: Nimrod
##
## var client = irc("picheta.me", joinChans = @["#bots"])
## client.connect()
## while True:
## var event: TIRCEvent
## if client.poll(event):
## case event.typ
## of EvConnected: nil
## of EvDisconnected:
## client.reconnect()
## of EvMsg:
## # Write your message reading code here.
##
## **Warning:** The API of this module is unstable, and therefore is subject
## to change.
include "system/inclrtl"
import sockets, strutils, parseutils, times, asyncio, os
type
TIRC* = object of TObject
address: string
port: TPort
nick, user, realname, serverPass: string
case isAsync: bool
of true:
handleEvent: proc (irc: PAsyncIRC, ev: TIRCEvent) {.closure, gcsafe.}
asyncSock: PAsyncSocket
myDispatcher: PDispatcher
of false:
dummyA: pointer
dummyB: pointer # workaround a Nimrod API issue
dummyC: pointer
sock: TSocket
status: TInfo
lastPing: float
lastPong: float
lag: float
channelsToJoin: seq[string]
msgLimit: bool
messageBuffer: seq[tuple[timeToSend: float, m: string]]
lastReconnect: float
PIRC* = ref TIRC
PAsyncIRC* = ref TAsyncIRC
TAsyncIRC* = object of TIRC
TIRCMType* = enum
MUnknown,
MNumeric,
MPrivMsg,
MJoin,
MPart,
MMode,
MTopic,
MInvite,
MKick,
MQuit,
MNick,
MNotice,
MPing,
MPong,
MError
TIRCEventType* = enum
EvMsg, EvConnected, EvDisconnected
TIRCEvent* = object ## IRC Event
case typ*: TIRCEventType
of EvConnected:
## Connected to server.
## Only occurs with AsyncIRC.
nil
of EvDisconnected:
## Disconnected from the server
nil
of EvMsg: ## Message from the server
cmd*: TIRCMType ## Command (e.g. PRIVMSG)
nick*, user*, host*, servername*: string
numeric*: string ## Only applies to ``MNumeric``
params*: seq[string] ## Parameters of the IRC message
origin*: string ## The channel/user that this msg originated from
raw*: string ## Raw IRC message
timestamp*: TTime ## UNIX epoch time the message was received
proc send*(irc: PIRC, message: string, sendImmediately = false) =
## Sends ``message`` as a raw command. It adds ``\c\L`` for you.
var sendMsg = true
if irc.msgLimit and not sendImmediately:
var timeToSend = epochTime()
if irc.messageBuffer.len() >= 3:
timeToSend = (irc.messageBuffer[irc.messageBuffer.len()-1][0] + 2.0)
irc.messageBuffer.add((timeToSend, message))
sendMsg = false
if sendMsg:
try:
if irc.isAsync:
irc.asyncSock.send(message & "\c\L")
else:
irc.sock.send(message & "\c\L")
except EOS:
# Assuming disconnection of every EOS could be bad,
# but I can't exactly check for EBrokenPipe.
irc.status = SockClosed
proc privmsg*(irc: PIRC, target, message: string) =
## Sends ``message`` to ``target``. ``Target`` can be a channel, or a user.
irc.send("PRIVMSG $1 :$2" % [target, message])
proc notice*(irc: PIRC, target, message: string) =
## Sends ``notice`` to ``target``. ``Target`` can be a channel, or a user.
irc.send("NOTICE $1 :$2" % [target, message])
proc join*(irc: PIRC, channel: string, key = "") =
## Joins ``channel``.
##
## If key is not ``""``, then channel is assumed to be key protected and this
## function will join the channel using ``key``.
if key == "":
irc.send("JOIN " & channel)
else:
irc.send("JOIN " & channel & " " & key)
proc part*(irc: PIRC, channel, message: string) =
## Leaves ``channel`` with ``message``.
irc.send("PART " & channel & " :" & message)
proc close*(irc: PIRC) =
## Closes connection to an IRC server.
##
## **Warning:** This procedure does not send a ``QUIT`` message to the server.
irc.status = SockClosed
if irc.isAsync:
irc.asyncSock.close()
else:
irc.sock.close()
proc isNumber(s: string): bool =
## Checks if `s` contains only numbers.
var i = 0
while s[i] in {'0'..'9'}: inc(i)
result = i == s.len and s.len > 0
proc parseMessage(msg: string): TIRCEvent =
result.typ = EvMsg
result.cmd = MUnknown
result.raw = msg
result.timestamp = times.getTime()
var i = 0
# Process the prefix
if msg[i] == ':':
inc(i) # Skip `:`
var nick = ""
i.inc msg.parseUntil(nick, {'!', ' '}, i)
result.nick = ""
result.serverName = ""
if msg[i] == '!':
result.nick = nick
inc(i) # Skip `!`
i.inc msg.parseUntil(result.user, {'@'}, i)
inc(i) # Skip `@`
i.inc msg.parseUntil(result.host, {' '}, i)
inc(i) # Skip ` `
else:
result.serverName = nick
inc(i) # Skip ` `
# Process command
var cmd = ""
i.inc msg.parseUntil(cmd, {' '}, i)
if cmd.isNumber:
result.cmd = MNumeric
result.numeric = cmd
else:
case cmd
of "PRIVMSG": result.cmd = MPrivMsg
of "JOIN": result.cmd = MJoin
of "PART": result.cmd = MPart
of "PONG": result.cmd = MPong
of "PING": result.cmd = MPing
of "MODE": result.cmd = MMode
of "TOPIC": result.cmd = MTopic
of "INVITE": result.cmd = MInvite
of "KICK": result.cmd = MKick
of "QUIT": result.cmd = MQuit
of "NICK": result.cmd = MNick
of "NOTICE": result.cmd = MNotice
of "ERROR": result.cmd = MError
else: result.cmd = MUnknown
# Don't skip space here. It is skipped in the following While loop.
# Params
result.params = @[]
var param = ""
while msg[i] != '\0' and msg[i] != ':':
inc(i) # Skip ` `.
i.inc msg.parseUntil(param, {' ', ':', '\0'}, i)
if param != "":
result.params.add(param)
param.setlen(0)
if msg[i] == ':':
inc(i) # Skip `:`.
result.params.add(msg[i..msg.len-1])
proc connect*(irc: PIRC) =
## Connects to an IRC server as specified by ``irc``.
assert(irc.address != "")
assert(irc.port != TPort(0))
irc.sock.connect(irc.address, irc.port)
irc.status = SockConnected
# Greet the server :)
if irc.serverPass != "": irc.send("PASS " & irc.serverPass, true)
irc.send("NICK " & irc.nick, true)
irc.send("USER $1 * 0 :$2" % [irc.user, irc.realname], true)
proc reconnect*(irc: PIRC, timeout = 5000) =
## Reconnects to an IRC server.
##
## ``Timeout`` specifies the time to wait in miliseconds between multiple
## consecutive reconnections.
##
## This should be used when an ``EvDisconnected`` event occurs.
let secSinceReconnect = int(epochTime() - irc.lastReconnect)
if secSinceReconnect < timeout:
sleep(timeout - secSinceReconnect)
irc.sock = socket()
if irc.sock == InvalidSocket: osError(osLastError())
irc.connect()
irc.lastReconnect = epochTime()
proc irc*(address: string, port: TPort = 6667.TPort,
nick = "NimrodBot",
user = "NimrodBot",
realname = "NimrodBot", serverPass = "",
joinChans: seq[string] = @[],
msgLimit: bool = true): PIRC =
## Creates a ``TIRC`` object.
new(result)
result.address = address
result.port = port
result.nick = nick
result.user = user
result.realname = realname
result.serverPass = serverPass
result.lastPing = epochTime()
result.lastPong = -1.0
result.lag = -1.0
result.channelsToJoin = joinChans
result.msgLimit = msgLimit
result.messageBuffer = @[]
result.status = SockIdle
result.sock = socket()
if result.sock == InvalidSocket: osError(osLastError())
proc processLine(irc: PIRC, line: string): TIRCEvent =
if line.len == 0:
irc.close()
result.typ = EvDisconnected
else:
result = parseMessage(line)
# Get the origin
result.origin = result.params[0]
if result.origin == irc.nick and
result.nick != "": result.origin = result.nick
if result.cmd == MError:
irc.close()
result.typ = EvDisconnected
return
if result.cmd == MPing:
irc.send("PONG " & result.params[0])
if result.cmd == MPong:
irc.lag = epochTime() - parseFloat(result.params[result.params.high])
irc.lastPong = epochTime()
if result.cmd == MNumeric:
if result.numeric == "001":
# Check the nickname.
if irc.nick != result.params[0]:
assert ' ' notin result.params[0]
irc.nick = result.params[0]
for chan in items(irc.channelsToJoin):
irc.join(chan)
if result.cmd == MNick:
if result.nick == irc.nick:
irc.nick = result.params[0]
proc processOther(irc: PIRC, ev: var TIRCEvent): bool =
result = false
if epochTime() - irc.lastPing >= 20.0:
irc.lastPing = epochTime()
irc.send("PING :" & formatFloat(irc.lastPing), true)
if epochTime() - irc.lastPong >= 120.0 and irc.lastPong != -1.0:
irc.close()
ev.typ = EvDisconnected # TODO: EvTimeout?
return true
for i in 0..irc.messageBuffer.len-1:
if epochTime() >= irc.messageBuffer[0][0]:
irc.send(irc.messageBuffer[0].m, true)
irc.messageBuffer.delete(0)
else:
break # messageBuffer is guaranteed to be from the quickest to the
# later-est.
proc poll*(irc: PIRC, ev: var TIRCEvent,
timeout: int = 500): bool =
## This function parses a single message from the IRC server and returns
## a TIRCEvent.
##
## This function should be called often as it also handles pinging
## the server.
##
## This function provides a somewhat asynchronous IRC implementation, although
## it should only be used for simple things for example an IRC bot which does
## not need to be running many time critical tasks in the background. If you
## require this, use the asyncio implementation.
if not (irc.status == SockConnected):
# Do not close the socket here, it is already closed!
ev.typ = EvDisconnected
var line = TaintedString""
var socks = @[irc.sock]
var ret = socks.select(timeout)
if ret == -1: osError(osLastError())
if socks.len() != 0 and ret != 0:
irc.sock.readLine(line)
ev = irc.processLine(line.string)
result = true
if processOther(irc, ev): result = true
proc getLag*(irc: PIRC): float =
## Returns the latency between this client and the IRC server in seconds.
##
## If latency is unknown, returns -1.0.
return irc.lag
proc isConnected*(irc: PIRC): bool =
## Returns whether this IRC client is connected to an IRC server.
return irc.status == SockConnected
proc getNick*(irc: PIRC): string =
## Returns the current nickname of the client.
return irc.nick
# -- Asyncio dispatcher
proc handleConnect(s: PAsyncSocket, irc: PAsyncIRC) =
# Greet the server :)
if irc.serverPass != "": irc.send("PASS " & irc.serverPass, true)
irc.send("NICK " & irc.nick, true)
irc.send("USER $1 * 0 :$2" % [irc.user, irc.realname], true)
irc.status = SockConnected
var ev: TIRCEvent
ev.typ = EvConnected
irc.handleEvent(irc, ev)
proc handleRead(s: PAsyncSocket, irc: PAsyncIRC) =
var line = "".TaintedString
var ret = s.readLine(line)
if ret:
if line == "":
var ev: TIRCEvent
irc.close()
ev.typ = EvDisconnected
irc.handleEvent(irc, ev)
else:
var ev = irc.processLine(line.string)
irc.handleEvent(irc, ev)
proc handleTask(s: PAsyncSocket, irc: PAsyncIRC) =
var ev: TIRCEvent
if irc.processOther(ev):
irc.handleEvent(irc, ev)
proc register*(d: PDispatcher, irc: PAsyncIRC) =
## Registers ``irc`` with dispatcher ``d``.
irc.asyncSock.handleConnect =
proc (s: PAsyncSocket) =
handleConnect(s, irc)
irc.asyncSock.handleRead =
proc (s: PAsyncSocket) =
handleRead(s, irc)
irc.asyncSock.handleTask =
proc (s: PAsyncSocket) =
handleTask(s, irc)
d.register(irc.asyncSock)
irc.myDispatcher = d
proc connect*(irc: PAsyncIRC) =
## Equivalent of connect for ``TIRC`` but specifically created for asyncio.
assert(irc.address != "")
assert(irc.port != TPort(0))
irc.asyncSock.connect(irc.address, irc.port)
proc reconnect*(irc: PAsyncIRC, timeout = 5000) =
## Reconnects to an IRC server.
##
## ``Timeout`` specifies the time to wait in miliseconds between multiple
## consecutive reconnections.
##
## This should be used when an ``EvDisconnected`` event occurs.
##
## When successfully reconnected an ``EvConnected`` event will occur.
let secSinceReconnect = int(epochTime() - irc.lastReconnect)
if secSinceReconnect < timeout:
sleep(timeout - secSinceReconnect)
irc.asyncSock = AsyncSocket()
irc.myDispatcher.register(irc)
irc.connect()
irc.lastReconnect = epochTime()
proc asyncIRC*(address: string, port: TPort = 6667.TPort,
nick = "NimrodBot",
user = "NimrodBot",
realname = "NimrodBot", serverPass = "",
joinChans: seq[string] = @[],
msgLimit: bool = true,
ircEvent: proc (irc: PAsyncIRC, ev: TIRCEvent) {.closure,gcsafe.}
): PAsyncIRC =
## Use this function if you want to use asyncio's dispatcher.
##
## **Note:** Do **NOT** use this if you're writing a simple IRC bot which only
## requires one task to be run, i.e. this should not be used if you want a
## synchronous IRC client implementation, use ``irc`` for that.
new(result)
result.isAsync = true
result.address = address
result.port = port
result.nick = nick
result.user = user
result.realname = realname
result.serverPass = serverPass
result.lastPing = epochTime()
result.lastPong = -1.0
result.lag = -1.0
result.channelsToJoin = joinChans
result.msgLimit = msgLimit
result.messageBuffer = @[]
result.handleEvent = ircEvent
result.asyncSock = AsyncSocket()
when isMainModule:
#var m = parseMessage("ERROR :Closing Link: dom96.co.cc (Ping timeout: 252 seconds)")
#echo(repr(m))
var client = irc("amber.tenthbit.net", nick="TestBot1234",
joinChans = @["#flood"])
client.connect()
while true:
var event: TIRCEvent
if client.poll(event):
case event.typ
of EvConnected:
discard
of EvDisconnected:
break
of EvMsg:
if event.cmd == MPrivMsg:
var msg = event.params[event.params.high]
if msg == "|test": client.privmsg(event.origin, "hello")
if msg == "|excessFlood":
for i in 0..10:
client.privmsg(event.origin, "TEST" & $i)
#echo( repr(event) )
#echo("Lag: ", formatFloat(client.getLag()))

View File

@@ -11,7 +11,7 @@
{.deadCodeElim: on.}
import rawsockets, os, strutils, unsigned, parseutils, times
export TPort, `$`
export TPort, `$`, `==`
const useWinVersion = defined(Windows) or defined(nimdoc)

View File

@@ -365,8 +365,9 @@ when defined(windows):
template getFilename(f: expr): expr = $f.cFilename
proc skipFindData(f: TWIN32_FIND_DATA): bool {.inline.} =
# Note - takes advantage of null delimiter in the cstring
const dot = ord('.')
result = f.cFileName[0].int == dot and(f.cFileName[1].int == 0 or
result = f.cFileName[0].int == dot and (f.cFileName[1].int == 0 or
f.cFileName[1].int == dot and f.cFileName[2].int == 0)
proc existsFile*(filename: string): bool {.rtl, extern: "nos$1",
@@ -1861,12 +1862,12 @@ proc expandTilde*(path: string): string =
when defined(Windows):
type
DeviceId = int32
FileId = int64
DeviceId* = int32
FileId* = int64
else:
type
DeviceId = TDev
FileId = TIno
DeviceId* = TDev
FileId* = TIno
type
FileInfo* = object
@@ -1909,6 +1910,7 @@ template rawToFormalFileInfo(rawInfo, formalInfo): expr =
if (rawInfo.dwFileAttributes and FILE_ATTRIBUTE_REPARSE_POINT) != 0'i32:
formalInfo.kind = succ(result.kind)
else:
template checkAndIncludeMode(rawMode, formalMode: expr) =
if (rawInfo.st_mode and rawMode) != 0'i32:
@@ -1995,4 +1997,26 @@ proc getFileInfo*(path: string, followSymlink = true): FileInfo =
osError(osLastError())
rawToFormalFileInfo(rawInfo, result)
proc isHidden*(path: string): bool =
## Determines whether a given path is hidden or not. Returns false if the
## file doesn't exist. The given path must be accessible from the current
## working directory of the program.
##
## On Windows, a file is hidden if the file's 'hidden' attribute is set.
## On Unix-like systems, a file is hidden if it starts with a '.' (period)
## and is not *just* '.' or '..' ' ."
when defined(Windows):
wrapUnary(attributes, getFileAttributesW, path)
if attributes != -1'i32:
result = (attributes and FILE_ATTRIBUTE_HIDDEN) != 0'i32
else:
if fileExists(path):
let
fileName = extractFilename(path)
nameLen = len(fileName)
if nameLen == 2:
result = (fileName[0] == '.') and (fileName[1] != '.')
elif nameLen > 2:
result = (fileName[0] == '.') and (fileName[3] != '.')
{.pop.}

View File

@@ -63,44 +63,44 @@ elif defined(windows):
elif defined(JS):
type
TTime* {.final, importc.} = object
getDay: proc (): int {.tags: [], raises: [].}
getFullYear: proc (): int {.tags: [], raises: [].}
getHours: proc (): int {.tags: [], raises: [].}
getMilliseconds: proc (): int {.tags: [], raises: [].}
getMinutes: proc (): int {.tags: [], raises: [].}
getMonth: proc (): int {.tags: [], raises: [].}
getSeconds: proc (): int {.tags: [], raises: [].}
getTime: proc (): int {.tags: [], raises: [].}
getTimezoneOffset: proc (): int {.tags: [], raises: [].}
getDate: proc (): int {.tags: [], raises: [].}
getUTCDate: proc (): int {.tags: [], raises: [].}
getUTCFullYear: proc (): int {.tags: [], raises: [].}
getUTCHours: proc (): int {.tags: [], raises: [].}
getUTCMilliseconds: proc (): int {.tags: [], raises: [].}
getUTCMinutes: proc (): int {.tags: [], raises: [].}
getUTCMonth: proc (): int {.tags: [], raises: [].}
getUTCSeconds: proc (): int {.tags: [], raises: [].}
getUTCDay: proc (): int {.tags: [], raises: [].}
getYear: proc (): int {.tags: [], raises: [].}
parse: proc (s: cstring): TTime {.tags: [], raises: [].}
setDate: proc (x: int) {.tags: [], raises: [].}
setFullYear: proc (x: int) {.tags: [], raises: [].}
setHours: proc (x: int) {.tags: [], raises: [].}
setMilliseconds: proc (x: int) {.tags: [], raises: [].}
setMinutes: proc (x: int) {.tags: [], raises: [].}
setMonth: proc (x: int) {.tags: [], raises: [].}
setSeconds: proc (x: int) {.tags: [], raises: [].}
setTime: proc (x: int) {.tags: [], raises: [].}
setUTCDate: proc (x: int) {.tags: [], raises: [].}
setUTCFullYear: proc (x: int) {.tags: [], raises: [].}
setUTCHours: proc (x: int) {.tags: [], raises: [].}
setUTCMilliseconds: proc (x: int) {.tags: [], raises: [].}
setUTCMinutes: proc (x: int) {.tags: [], raises: [].}
setUTCMonth: proc (x: int) {.tags: [], raises: [].}
setUTCSeconds: proc (x: int) {.tags: [], raises: [].}
setYear: proc (x: int) {.tags: [], raises: [].}
toGMTString: proc (): cstring {.tags: [], raises: [].}
toLocaleString: proc (): cstring {.tags: [], raises: [].}
getDay: proc (): int {.tags: [], raises: [], gcsafe.}
getFullYear: proc (): int {.tags: [], raises: [], gcsafe.}
getHours: proc (): int {.tags: [], raises: [], gcsafe.}
getMilliseconds: proc (): int {.tags: [], raises: [], gcsafe.}
getMinutes: proc (): int {.tags: [], raises: [], gcsafe.}
getMonth: proc (): int {.tags: [], raises: [], gcsafe.}
getSeconds: proc (): int {.tags: [], raises: [], gcsafe.}
getTime: proc (): int {.tags: [], raises: [], gcsafe.}
getTimezoneOffset: proc (): int {.tags: [], raises: [], gcsafe.}
getDate: proc (): int {.tags: [], raises: [], gcsafe.}
getUTCDate: proc (): int {.tags: [], raises: [], gcsafe.}
getUTCFullYear: proc (): int {.tags: [], raises: [], gcsafe.}
getUTCHours: proc (): int {.tags: [], raises: [], gcsafe.}
getUTCMilliseconds: proc (): int {.tags: [], raises: [], gcsafe.}
getUTCMinutes: proc (): int {.tags: [], raises: [], gcsafe.}
getUTCMonth: proc (): int {.tags: [], raises: [], gcsafe.}
getUTCSeconds: proc (): int {.tags: [], raises: [], gcsafe.}
getUTCDay: proc (): int {.tags: [], raises: [], gcsafe.}
getYear: proc (): int {.tags: [], raises: [], gcsafe.}
parse: proc (s: cstring): TTime {.tags: [], raises: [], gcsafe.}
setDate: proc (x: int) {.tags: [], raises: [], gcsafe.}
setFullYear: proc (x: int) {.tags: [], raises: [], gcsafe.}
setHours: proc (x: int) {.tags: [], raises: [], gcsafe.}
setMilliseconds: proc (x: int) {.tags: [], raises: [], gcsafe.}
setMinutes: proc (x: int) {.tags: [], raises: [], gcsafe.}
setMonth: proc (x: int) {.tags: [], raises: [], gcsafe.}
setSeconds: proc (x: int) {.tags: [], raises: [], gcsafe.}
setTime: proc (x: int) {.tags: [], raises: [], gcsafe.}
setUTCDate: proc (x: int) {.tags: [], raises: [], gcsafe.}
setUTCFullYear: proc (x: int) {.tags: [], raises: [], gcsafe.}
setUTCHours: proc (x: int) {.tags: [], raises: [], gcsafe.}
setUTCMilliseconds: proc (x: int) {.tags: [], raises: [], gcsafe.}
setUTCMinutes: proc (x: int) {.tags: [], raises: [], gcsafe.}
setUTCMonth: proc (x: int) {.tags: [], raises: [], gcsafe.}
setUTCSeconds: proc (x: int) {.tags: [], raises: [], gcsafe.}
setYear: proc (x: int) {.tags: [], raises: [], gcsafe.}
toGMTString: proc (): cstring {.tags: [], raises: [], gcsafe.}
toLocaleString: proc (): cstring {.tags: [], raises: [], gcsafe.}
type
TTimeInfo* = object of TObject ## represents a time in different parts

View File

@@ -1,6 +1,6 @@
discard """
line: 7
errormsg: "type mismatch"
errormsg: "expression 'items' cannot be called"
"""
type a = enum b,c,d

10
tests/misc/tissue710.nim Normal file
View File

@@ -0,0 +1,10 @@
discard """
file: "tissue710.nim"
line: 8
errorMsg: "expression '||' cannot be called"
"""
var sum = 0
for x in 3..1000:
if (x mod 3 == 0) || (x mod 5 == 0):
sum += x
echo(sum)