Merge branch 'devel' into bugfix-2858-testament-sources-system-wide
This commit is contained in:
commit
f0b6c03b26
46 changed files with 344 additions and 1226 deletions
0
bootstrap.sh
Normal file → Executable file
0
bootstrap.sh
Normal file → Executable file
|
|
@ -1,6 +1,6 @@
|
||||||
[Package]
|
[Package]
|
||||||
name = "compiler"
|
name = "compiler"
|
||||||
version = "0.10.3"
|
version = "0.11.3"
|
||||||
author = "Andreas Rumpf"
|
author = "Andreas Rumpf"
|
||||||
description = "Compiler package providing the compiler sources as a library."
|
description = "Compiler package providing the compiler sources as a library."
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
@ -8,4 +8,4 @@ license = "MIT"
|
||||||
InstallDirs = "doc, compiler"
|
InstallDirs = "doc, compiler"
|
||||||
|
|
||||||
[Deps]
|
[Deps]
|
||||||
Requires: "nim >= 0.10.3"
|
Requires: "nim >= 0.11.3"
|
||||||
|
|
|
||||||
|
|
@ -423,6 +423,7 @@ type
|
||||||
# but unfortunately it has measurable impact for compilation
|
# but unfortunately it has measurable impact for compilation
|
||||||
# efficiency
|
# efficiency
|
||||||
nfTransf, # node has been transformed
|
nfTransf, # node has been transformed
|
||||||
|
nfNoRewrite # node should not be transformed anymore
|
||||||
nfSem # node has been checked for semantics
|
nfSem # node has been checked for semantics
|
||||||
nfLL # node has gone through lambda lifting
|
nfLL # node has gone through lambda lifting
|
||||||
nfDotField # the call can use a dot operator
|
nfDotField # the call can use a dot operator
|
||||||
|
|
@ -1345,7 +1346,7 @@ proc propagateToOwner*(owner, elem: PType) =
|
||||||
owner.flags.incl tfHasAsgn
|
owner.flags.incl tfHasAsgn
|
||||||
|
|
||||||
if owner.kind notin {tyProc, tyGenericInst, tyGenericBody,
|
if owner.kind notin {tyProc, tyGenericInst, tyGenericBody,
|
||||||
tyGenericInvocation}:
|
tyGenericInvocation, tyPtr}:
|
||||||
let elemB = elem.skipTypes({tyGenericInst})
|
let elemB = elem.skipTypes({tyGenericInst})
|
||||||
if elemB.isGCedMem or tfHasGCedMem in elemB.flags:
|
if elemB.isGCedMem or tfHasGCedMem in elemB.flags:
|
||||||
# for simplicity, we propagate this flag even to generics. We then
|
# for simplicity, we propagate this flag even to generics. We then
|
||||||
|
|
|
||||||
|
|
@ -2150,7 +2150,7 @@ proc genNamedConstExpr(p: BProc, n: PNode): Rope =
|
||||||
proc genConstSimpleList(p: BProc, n: PNode): Rope =
|
proc genConstSimpleList(p: BProc, n: PNode): Rope =
|
||||||
var length = sonsLen(n)
|
var length = sonsLen(n)
|
||||||
result = rope("{")
|
result = rope("{")
|
||||||
for i in countup(0, length - 2):
|
for i in countup(ord(n.kind == nkObjConstr), length - 2):
|
||||||
addf(result, "$1,$n", [genNamedConstExpr(p, n.sons[i])])
|
addf(result, "$1,$n", [genNamedConstExpr(p, n.sons[i])])
|
||||||
if length > 0: add(result, genNamedConstExpr(p, n.sons[length - 1]))
|
if length > 0: add(result, genNamedConstExpr(p, n.sons[length - 1]))
|
||||||
addf(result, "}$n", [])
|
addf(result, "}$n", [])
|
||||||
|
|
|
||||||
|
|
@ -721,6 +721,8 @@ proc genProcPrototype(m: BModule, sym: PSym) =
|
||||||
getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym)))
|
getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym)))
|
||||||
elif not containsOrIncl(m.declaredProtos, sym.id):
|
elif not containsOrIncl(m.declaredProtos, sym.id):
|
||||||
var header = genProcHeader(m, sym)
|
var header = genProcHeader(m, sym)
|
||||||
|
if sfNoReturn in sym.flags and hasDeclspec in extccomp.CC[cCompiler].props:
|
||||||
|
header = "__declspec(noreturn) " & header
|
||||||
if sym.typ.callConv != ccInline and crossesCppBoundary(m, sym):
|
if sym.typ.callConv != ccInline and crossesCppBoundary(m, sym):
|
||||||
header = "extern \"C\" " & header
|
header = "extern \"C\" " & header
|
||||||
if sfPure in sym.flags and hasAttribute in CC[cCompiler].props:
|
if sfPure in sym.flags and hasAttribute in CC[cCompiler].props:
|
||||||
|
|
|
||||||
|
|
@ -946,7 +946,11 @@ proc transformOuterProc(o: POuterContext, n: PNode; it: TIter): PNode =
|
||||||
proc liftLambdas*(fn: PSym, body: PNode): PNode =
|
proc liftLambdas*(fn: PSym, body: PNode): PNode =
|
||||||
# XXX gCmd == cmdCompileToJS does not suffice! The compiletime stuff needs
|
# XXX gCmd == cmdCompileToJS does not suffice! The compiletime stuff needs
|
||||||
# the transformation even when compiling to JS ...
|
# the transformation even when compiling to JS ...
|
||||||
if body.kind == nkEmpty or gCmd == cmdCompileToJS or
|
|
||||||
|
# However we can do lifting for the stuff which is *only* compiletime.
|
||||||
|
let isCompileTime = sfCompileTime in fn.flags or fn.kind == skMacro
|
||||||
|
|
||||||
|
if body.kind == nkEmpty or (gCmd == cmdCompileToJS and not isCompileTime) or
|
||||||
fn.skipGenericOwner.kind != skModule:
|
fn.skipGenericOwner.kind != skModule:
|
||||||
# ignore forward declaration:
|
# ignore forward declaration:
|
||||||
result = body
|
result = body
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,9 @@ type
|
||||||
errNoneSpeedOrSizeExpectedButXFound, errGuiConsoleOrLibExpectedButXFound,
|
errNoneSpeedOrSizeExpectedButXFound, errGuiConsoleOrLibExpectedButXFound,
|
||||||
errUnknownOS, errUnknownCPU, errGenOutExpectedButXFound,
|
errUnknownOS, errUnknownCPU, errGenOutExpectedButXFound,
|
||||||
errArgsNeedRunOption, errInvalidMultipleAsgn, errColonOrEqualsExpected,
|
errArgsNeedRunOption, errInvalidMultipleAsgn, errColonOrEqualsExpected,
|
||||||
errExprExpected, errUndeclaredIdentifier, errUseQualifier, errTypeExpected,
|
errExprExpected, errUndeclaredIdentifier, errUndeclaredField,
|
||||||
|
errUndeclaredRoutine, errUseQualifier,
|
||||||
|
errTypeExpected,
|
||||||
errSystemNeeds, errExecutionOfProgramFailed, errNotOverloadable,
|
errSystemNeeds, errExecutionOfProgramFailed, errNotOverloadable,
|
||||||
errInvalidArgForX, errStmtHasNoEffect, errXExpectsTypeOrValue,
|
errInvalidArgForX, errStmtHasNoEffect, errXExpectsTypeOrValue,
|
||||||
errXExpectsArrayType, errIteratorCannotBeInstantiated, errExprXAmbiguous,
|
errXExpectsArrayType, errIteratorCannotBeInstantiated, errExprXAmbiguous,
|
||||||
|
|
@ -190,6 +192,8 @@ const
|
||||||
errColonOrEqualsExpected: "\':\' or \'=\' expected, but found \'$1\'",
|
errColonOrEqualsExpected: "\':\' or \'=\' expected, but found \'$1\'",
|
||||||
errExprExpected: "expression expected, but found \'$1\'",
|
errExprExpected: "expression expected, but found \'$1\'",
|
||||||
errUndeclaredIdentifier: "undeclared identifier: \'$1\'",
|
errUndeclaredIdentifier: "undeclared identifier: \'$1\'",
|
||||||
|
errUndeclaredField: "undeclared field: \'$1\'",
|
||||||
|
errUndeclaredRoutine: "attempting to call undeclared routine: \'$1\'",
|
||||||
errUseQualifier: "ambiguous identifier: \'$1\' -- use a qualifier",
|
errUseQualifier: "ambiguous identifier: \'$1\' -- use a qualifier",
|
||||||
errTypeExpected: "type expected",
|
errTypeExpected: "type expected",
|
||||||
errSystemNeeds: "system module needs \'$1\'",
|
errSystemNeeds: "system module needs \'$1\'",
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,10 @@
|
||||||
## Nimfix is a tool that helps to convert old-style Nimrod code to Nim code.
|
## Nimfix is a tool that helps to convert old-style Nimrod code to Nim code.
|
||||||
|
|
||||||
import strutils, os, parseopt
|
import strutils, os, parseopt
|
||||||
import options, commands, modules, sem, passes, passaux, pretty, msgs, nimconf,
|
import compiler/options, compiler/commands, compiler/modules, compiler/sem,
|
||||||
extccomp, condsyms, lists
|
compiler/passes, compiler/passaux, compiler/nimfix/pretty,
|
||||||
|
compiler/msgs, compiler/nimconf,
|
||||||
|
compiler/extccomp, compiler/condsyms, compiler/lists
|
||||||
|
|
||||||
const Usage = """
|
const Usage = """
|
||||||
Nimfix - Tool to patch Nim code
|
Nimfix - Tool to patch Nim code
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,10 @@
|
||||||
## to convert Nim code into a consistent style.
|
## to convert Nim code into a consistent style.
|
||||||
|
|
||||||
import
|
import
|
||||||
strutils, os, options, ast, astalgo, msgs, ropes, idents,
|
strutils, os, intsets, strtabs
|
||||||
intsets, strtabs, semdata, prettybase
|
|
||||||
|
import compiler/options, compiler/ast, compiler/astalgo, compiler/msgs,
|
||||||
|
compiler/semdata, compiler/nimfix/prettybase, compiler/ropes, compiler/idents
|
||||||
|
|
||||||
type
|
type
|
||||||
StyleCheck* {.pure.} = enum None, Warn, Auto
|
StyleCheck* {.pure.} = enum None, Warn, Auto
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
import ast, msgs, strutils, idents, lexbase, streams
|
import strutils, lexbase, streams
|
||||||
|
import compiler/ast, compiler/msgs, compiler/idents
|
||||||
from os import splitFile
|
from os import splitFile
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -7,330 +7,6 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
## Nimsuggest is a tool that helps to give editors IDE like capabilities.
|
## Nimsuggest has been moved to https://github.com/nim-lang/nimsuggest
|
||||||
|
|
||||||
import strutils, os, parseopt, parseutils, sequtils, net
|
{.error: "This project has moved to the following repo: https://github.com/nim-lang/nimsuggest".}
|
||||||
# Do NOT import suggest. It will lead to wierd bugs with
|
|
||||||
# suggestionResultHook, because suggest.nim is included by sigmatch.
|
|
||||||
# So we import that one instead.
|
|
||||||
import options, commands, modules, sem, passes, passaux, msgs, nimconf,
|
|
||||||
extccomp, condsyms, lists, net, rdstdin, sexp, sigmatch, ast
|
|
||||||
|
|
||||||
when defined(windows):
|
|
||||||
import winlean
|
|
||||||
else:
|
|
||||||
import posix
|
|
||||||
|
|
||||||
const Usage = """
|
|
||||||
Nimsuggest - Tool to give every editor IDE like capabilities for Nim
|
|
||||||
Usage:
|
|
||||||
nimsuggest [options] projectfile.nim
|
|
||||||
|
|
||||||
Options:
|
|
||||||
--port:PORT port, by default 6000
|
|
||||||
--address:HOST binds to that address, by default ""
|
|
||||||
--stdin read commands from stdin and write results to
|
|
||||||
stdout instead of using sockets
|
|
||||||
--epc use emacs epc mode
|
|
||||||
|
|
||||||
The server then listens to the connection and takes line-based commands.
|
|
||||||
|
|
||||||
In addition, all command line options of Nim that do not affect code generation
|
|
||||||
are supported.
|
|
||||||
"""
|
|
||||||
type
|
|
||||||
Mode = enum mstdin, mtcp, mepc
|
|
||||||
|
|
||||||
var
|
|
||||||
gPort = 6000.Port
|
|
||||||
gAddress = ""
|
|
||||||
gMode: Mode
|
|
||||||
|
|
||||||
const
|
|
||||||
seps = {':', ';', ' ', '\t'}
|
|
||||||
Help = "usage: sug|con|def|use file.nim[;dirtyfile.nim]:line:col\n"&
|
|
||||||
"type 'quit' to quit\n" &
|
|
||||||
"type 'debug' to toggle debug mode on/off\n" &
|
|
||||||
"type 'terse' to toggle terse mode on/off"
|
|
||||||
|
|
||||||
type
|
|
||||||
EUnexpectedCommand = object of Exception
|
|
||||||
|
|
||||||
proc parseQuoted(cmd: string; outp: var string; start: int): int =
|
|
||||||
var i = start
|
|
||||||
i += skipWhitespace(cmd, i)
|
|
||||||
if cmd[i] == '"':
|
|
||||||
i += parseUntil(cmd, outp, '"', i+1)+2
|
|
||||||
else:
|
|
||||||
i += parseUntil(cmd, outp, seps, i)
|
|
||||||
result = i
|
|
||||||
|
|
||||||
proc sexp(s: IdeCmd): SexpNode = sexp($s)
|
|
||||||
|
|
||||||
proc sexp(s: TSymKind): SexpNode = sexp($s)
|
|
||||||
|
|
||||||
proc sexp(s: Suggest): SexpNode =
|
|
||||||
# If you change the oder here, make sure to change it over in
|
|
||||||
# nim-mode.el too.
|
|
||||||
result = convertSexp([
|
|
||||||
s.section,
|
|
||||||
s.symkind,
|
|
||||||
s.qualifiedPath.map(newSString),
|
|
||||||
s.filePath,
|
|
||||||
s.forth,
|
|
||||||
s.line,
|
|
||||||
s.column,
|
|
||||||
s.doc
|
|
||||||
])
|
|
||||||
|
|
||||||
proc sexp(s: seq[Suggest]): SexpNode =
|
|
||||||
result = newSList()
|
|
||||||
for sug in s:
|
|
||||||
result.add(sexp(sug))
|
|
||||||
|
|
||||||
proc listEPC(): SexpNode =
|
|
||||||
let
|
|
||||||
argspecs = sexp("file line column dirtyfile".split(" ").map(newSSymbol))
|
|
||||||
docstring = sexp("line starts at 1, column at 0, dirtyfile is optional")
|
|
||||||
result = newSList()
|
|
||||||
for command in ["sug", "con", "def", "use"]:
|
|
||||||
let
|
|
||||||
cmd = sexp(command)
|
|
||||||
methodDesc = newSList()
|
|
||||||
methodDesc.add(cmd)
|
|
||||||
methodDesc.add(argspecs)
|
|
||||||
methodDesc.add(docstring)
|
|
||||||
result.add(methodDesc)
|
|
||||||
|
|
||||||
proc execute(cmd: IdeCmd, file, dirtyfile: string, line, col: int) =
|
|
||||||
gIdeCmd = cmd
|
|
||||||
if cmd == ideUse:
|
|
||||||
modules.resetAllModules()
|
|
||||||
var isKnownFile = true
|
|
||||||
let dirtyIdx = file.fileInfoIdx(isKnownFile)
|
|
||||||
|
|
||||||
if dirtyfile.len != 0: msgs.setDirtyFile(dirtyIdx, dirtyfile)
|
|
||||||
else: msgs.setDirtyFile(dirtyIdx, nil)
|
|
||||||
|
|
||||||
resetModule dirtyIdx
|
|
||||||
if dirtyIdx != gProjectMainIdx:
|
|
||||||
resetModule gProjectMainIdx
|
|
||||||
|
|
||||||
gTrackPos = newLineInfo(dirtyIdx, line, col)
|
|
||||||
gErrorCounter = 0
|
|
||||||
if not isKnownFile:
|
|
||||||
compileProject()
|
|
||||||
compileProject(dirtyIdx)
|
|
||||||
|
|
||||||
proc executeEPC(cmd: IdeCmd, args: SexpNode) =
|
|
||||||
let
|
|
||||||
file = args[0].getStr
|
|
||||||
line = args[1].getNum
|
|
||||||
column = args[2].getNum
|
|
||||||
var dirtyfile = ""
|
|
||||||
if len(args) > 3:
|
|
||||||
dirtyfile = args[3].getStr(nil)
|
|
||||||
execute(cmd, file, dirtyfile, int(line), int(column))
|
|
||||||
|
|
||||||
proc returnEPC(socket: var Socket, uid: BiggestInt, s: SexpNode, return_symbol = "return") =
|
|
||||||
let response = $convertSexp([newSSymbol(return_symbol), uid, s])
|
|
||||||
socket.send(toHex(len(response), 6))
|
|
||||||
socket.send(response)
|
|
||||||
|
|
||||||
proc connectToNextFreePort(server: Socket, host: string, start = 30000): int =
|
|
||||||
result = start
|
|
||||||
while true:
|
|
||||||
try:
|
|
||||||
server.bindaddr(Port(result), host)
|
|
||||||
return
|
|
||||||
except OsError:
|
|
||||||
when defined(windows):
|
|
||||||
let checkFor = WSAEADDRINUSE.OSErrorCode
|
|
||||||
else:
|
|
||||||
let checkFor = EADDRINUSE.OSErrorCode
|
|
||||||
if osLastError() != checkFor:
|
|
||||||
raise getCurrentException()
|
|
||||||
else:
|
|
||||||
result += 1
|
|
||||||
|
|
||||||
proc parseCmdLine(cmd: string) =
|
|
||||||
template toggle(sw) =
|
|
||||||
if sw in gGlobalOptions:
|
|
||||||
excl(gGlobalOptions, sw)
|
|
||||||
else:
|
|
||||||
incl(gGlobalOptions, sw)
|
|
||||||
return
|
|
||||||
|
|
||||||
template err() =
|
|
||||||
echo Help
|
|
||||||
return
|
|
||||||
|
|
||||||
var opc = ""
|
|
||||||
var i = parseIdent(cmd, opc, 0)
|
|
||||||
case opc.normalize
|
|
||||||
of "sug": gIdeCmd = ideSug
|
|
||||||
of "con": gIdeCmd = ideCon
|
|
||||||
of "def": gIdeCmd = ideDef
|
|
||||||
of "use": gIdeCmd = ideUse
|
|
||||||
of "quit": quit()
|
|
||||||
of "debug": toggle optIdeDebug
|
|
||||||
of "terse": toggle optIdeTerse
|
|
||||||
else: err()
|
|
||||||
var dirtyfile = ""
|
|
||||||
var orig = ""
|
|
||||||
i = parseQuoted(cmd, orig, i)
|
|
||||||
if cmd[i] == ';':
|
|
||||||
i = parseQuoted(cmd, dirtyfile, i+1)
|
|
||||||
i += skipWhile(cmd, seps, i)
|
|
||||||
var line = -1
|
|
||||||
var col = 0
|
|
||||||
i += parseInt(cmd, line, i)
|
|
||||||
i += skipWhile(cmd, seps, i)
|
|
||||||
i += parseInt(cmd, col, i)
|
|
||||||
|
|
||||||
execute(gIdeCmd, orig, dirtyfile, line, col-1)
|
|
||||||
|
|
||||||
proc serve() =
|
|
||||||
case gMode:
|
|
||||||
of mstdin:
|
|
||||||
echo Help
|
|
||||||
var line = ""
|
|
||||||
while readLineFromStdin("> ", line):
|
|
||||||
parseCmdLine line
|
|
||||||
echo ""
|
|
||||||
flushFile(stdout)
|
|
||||||
of mtcp:
|
|
||||||
var server = newSocket()
|
|
||||||
server.bindAddr(gPort, gAddress)
|
|
||||||
var inp = "".TaintedString
|
|
||||||
server.listen()
|
|
||||||
|
|
||||||
while true:
|
|
||||||
var stdoutSocket = newSocket()
|
|
||||||
msgs.writelnHook = proc (line: string) =
|
|
||||||
stdoutSocket.send(line & "\c\L")
|
|
||||||
|
|
||||||
accept(server, stdoutSocket)
|
|
||||||
|
|
||||||
stdoutSocket.readLine(inp)
|
|
||||||
parseCmdLine inp.string
|
|
||||||
|
|
||||||
stdoutSocket.send("\c\L")
|
|
||||||
stdoutSocket.close()
|
|
||||||
of mepc:
|
|
||||||
var server = newSocket()
|
|
||||||
let port = connectToNextFreePort(server, "localhost")
|
|
||||||
var inp = "".TaintedString
|
|
||||||
server.listen()
|
|
||||||
echo(port)
|
|
||||||
var client = newSocket()
|
|
||||||
# Wait for connection
|
|
||||||
accept(server, client)
|
|
||||||
while true:
|
|
||||||
var sizeHex = ""
|
|
||||||
if client.recv(sizeHex, 6) != 6:
|
|
||||||
raise newException(ValueError, "didn't get all the hexbytes")
|
|
||||||
var size = 0
|
|
||||||
if parseHex(sizeHex, size) == 0:
|
|
||||||
raise newException(ValueError, "invalid size hex: " & $sizeHex)
|
|
||||||
var messageBuffer = ""
|
|
||||||
if client.recv(messageBuffer, size) != size:
|
|
||||||
raise newException(ValueError, "didn't get all the bytes")
|
|
||||||
let
|
|
||||||
message = parseSexp($messageBuffer)
|
|
||||||
messageType = message[0].getSymbol
|
|
||||||
case messageType:
|
|
||||||
of "call":
|
|
||||||
var results: seq[Suggest] = @[]
|
|
||||||
suggestionResultHook = proc (s: Suggest) =
|
|
||||||
results.add(s)
|
|
||||||
|
|
||||||
let
|
|
||||||
uid = message[1].getNum
|
|
||||||
cmd = parseIdeCmd(message[2].getSymbol)
|
|
||||||
args = message[3]
|
|
||||||
executeEPC(cmd, args)
|
|
||||||
returnEPC(client, uid, sexp(results))
|
|
||||||
of "return":
|
|
||||||
raise newException(EUnexpectedCommand, "no return expected")
|
|
||||||
of "return-error":
|
|
||||||
raise newException(EUnexpectedCommand, "no return expected")
|
|
||||||
of "epc-error":
|
|
||||||
stderr.writeln("recieved epc error: " & $messageBuffer)
|
|
||||||
raise newException(IOError, "epc error")
|
|
||||||
of "methods":
|
|
||||||
returnEPC(client, message[1].getNum, listEPC())
|
|
||||||
else:
|
|
||||||
raise newException(EUnexpectedCommand, "unexpected call: " & messageType)
|
|
||||||
|
|
||||||
proc mainCommand =
|
|
||||||
registerPass verbosePass
|
|
||||||
registerPass semPass
|
|
||||||
gCmd = cmdIdeTools
|
|
||||||
incl gGlobalOptions, optCaasEnabled
|
|
||||||
isServing = true
|
|
||||||
wantMainModule()
|
|
||||||
appendStr(searchPaths, options.libpath)
|
|
||||||
if gProjectFull.len != 0:
|
|
||||||
# current path is always looked first for modules
|
|
||||||
prependStr(searchPaths, gProjectPath)
|
|
||||||
|
|
||||||
# do not stop after the first error:
|
|
||||||
msgs.gErrorMax = high(int)
|
|
||||||
compileProject()
|
|
||||||
serve()
|
|
||||||
|
|
||||||
proc processCmdLine*(pass: TCmdLinePass, cmd: string) =
|
|
||||||
var p = parseopt.initOptParser(cmd)
|
|
||||||
while true:
|
|
||||||
parseopt.next(p)
|
|
||||||
case p.kind
|
|
||||||
of cmdEnd: break
|
|
||||||
of cmdLongoption, cmdShortOption:
|
|
||||||
case p.key.normalize
|
|
||||||
of "port":
|
|
||||||
gPort = parseInt(p.val).Port
|
|
||||||
gMode = mtcp
|
|
||||||
of "address":
|
|
||||||
gAddress = p.val
|
|
||||||
gMode = mtcp
|
|
||||||
of "stdin": gMode = mstdin
|
|
||||||
of "epc":
|
|
||||||
gMode = mepc
|
|
||||||
gVerbosity = 0 # Port number gotta be first.
|
|
||||||
else: processSwitch(pass, p)
|
|
||||||
of cmdArgument:
|
|
||||||
options.gProjectName = unixToNativePath(p.key)
|
|
||||||
# if processArgument(pass, p, argsCount): break
|
|
||||||
|
|
||||||
proc handleCmdLine() =
|
|
||||||
if paramCount() == 0:
|
|
||||||
stdout.writeln(Usage)
|
|
||||||
else:
|
|
||||||
processCmdLine(passCmd1, "")
|
|
||||||
if gProjectName != "":
|
|
||||||
try:
|
|
||||||
gProjectFull = canonicalizePath(gProjectName)
|
|
||||||
except OSError:
|
|
||||||
gProjectFull = gProjectName
|
|
||||||
var p = splitFile(gProjectFull)
|
|
||||||
gProjectPath = p.dir
|
|
||||||
gProjectName = p.name
|
|
||||||
else:
|
|
||||||
gProjectPath = getCurrentDir()
|
|
||||||
loadConfigs(DefaultConfig) # load all config files
|
|
||||||
# now process command line arguments again, because some options in the
|
|
||||||
# command line can overwite the config file's settings
|
|
||||||
extccomp.initVars()
|
|
||||||
processCmdLine(passCmd2, "")
|
|
||||||
mainCommand()
|
|
||||||
|
|
||||||
when false:
|
|
||||||
proc quitCalled() {.noconv.} =
|
|
||||||
writeStackTrace()
|
|
||||||
|
|
||||||
addQuitProc(quitCalled)
|
|
||||||
|
|
||||||
condsyms.initDefines()
|
|
||||||
defineSymbol "nimsuggest"
|
|
||||||
handleCmdline()
|
|
||||||
|
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
# Special configuration file for the Nim project
|
|
||||||
|
|
||||||
gc:markAndSweep
|
|
||||||
|
|
||||||
hint[XDeclaredButNotUsed]:off
|
|
||||||
path:"$projectPath/../.."
|
|
||||||
|
|
||||||
path:"$lib/packages/docutils"
|
|
||||||
path:"../../compiler"
|
|
||||||
|
|
||||||
define:useStdoutAsStdmsg
|
|
||||||
define:nimsuggest
|
|
||||||
|
|
||||||
cs:partial
|
|
||||||
#define:useNodeIds
|
|
||||||
define:booting
|
|
||||||
#define:noDocgen
|
|
||||||
|
|
@ -64,6 +64,7 @@ proc setBaseFlags*(n: PNode, base: TNumericalBase)
|
||||||
proc parseSymbol*(p: var TParser, allowNil = false): PNode
|
proc parseSymbol*(p: var TParser, allowNil = false): PNode
|
||||||
proc parseTry(p: var TParser; isExpr: bool): PNode
|
proc parseTry(p: var TParser; isExpr: bool): PNode
|
||||||
proc parseCase(p: var TParser): PNode
|
proc parseCase(p: var TParser): PNode
|
||||||
|
proc parseStmtPragma(p: var TParser): PNode
|
||||||
# implementation
|
# implementation
|
||||||
|
|
||||||
proc getTok(p: var TParser) =
|
proc getTok(p: var TParser) =
|
||||||
|
|
@ -499,9 +500,12 @@ proc parsePar(p: var TParser): PNode =
|
||||||
#| parKeyw = 'discard' | 'include' | 'if' | 'while' | 'case' | 'try'
|
#| parKeyw = 'discard' | 'include' | 'if' | 'while' | 'case' | 'try'
|
||||||
#| | 'finally' | 'except' | 'for' | 'block' | 'const' | 'let'
|
#| | 'finally' | 'except' | 'for' | 'block' | 'const' | 'let'
|
||||||
#| | 'when' | 'var' | 'mixin'
|
#| | 'when' | 'var' | 'mixin'
|
||||||
#| par = '(' optInd (&parKeyw complexOrSimpleStmt ^+ ';'
|
#| par = '(' optInd
|
||||||
#| | simpleExpr ('=' expr (';' complexOrSimpleStmt ^+ ';' )? )?
|
#| ( &parKeyw complexOrSimpleStmt ^+ ';'
|
||||||
#| | (':' expr)? (',' (exprColonEqExpr comma?)*)? )?
|
#| | ';' complexOrSimpleStmt ^+ ';'
|
||||||
|
#| | pragmaStmt
|
||||||
|
#| | simpleExpr ( ('=' expr (';' complexOrSimpleStmt ^+ ';' )? )
|
||||||
|
#| | (':' expr (',' exprColonEqExpr ^+ ',' )? ) ) )
|
||||||
#| optPar ')'
|
#| optPar ')'
|
||||||
#
|
#
|
||||||
# unfortunately it's ambiguous: (expr: expr) vs (exprStmt); however a
|
# unfortunately it's ambiguous: (expr: expr) vs (exprStmt); however a
|
||||||
|
|
@ -521,6 +525,8 @@ proc parsePar(p: var TParser): PNode =
|
||||||
getTok(p)
|
getTok(p)
|
||||||
optInd(p, result)
|
optInd(p, result)
|
||||||
semiStmtList(p, result)
|
semiStmtList(p, result)
|
||||||
|
elif p.tok.tokType == tkCurlyDotLe:
|
||||||
|
result.add(parseStmtPragma(p))
|
||||||
elif p.tok.tokType != tkParRi:
|
elif p.tok.tokType != tkParRi:
|
||||||
var a = simpleExpr(p)
|
var a = simpleExpr(p)
|
||||||
if p.tok.tokType == tkEquals:
|
if p.tok.tokType == tkEquals:
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,9 @@ proc matchNested(c: PPatternContext, p, n: PNode, rpn: bool): bool =
|
||||||
|
|
||||||
proc matches(c: PPatternContext, p, n: PNode): bool =
|
proc matches(c: PPatternContext, p, n: PNode): bool =
|
||||||
# hidden conversions (?)
|
# hidden conversions (?)
|
||||||
if isPatternParam(c, p):
|
if nfNoRewrite in n.flags:
|
||||||
|
result = false
|
||||||
|
elif isPatternParam(c, p):
|
||||||
result = bindOrCheck(c, p.sym, n)
|
result = bindOrCheck(c, p.sym, n)
|
||||||
elif n.kind == nkSym and p.kind == nkIdent:
|
elif n.kind == nkSym and p.kind == nkIdent:
|
||||||
result = p.ident.id == n.sym.name.id
|
result = p.ident.id == n.sym.name.id
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@
|
||||||
|
|
||||||
## The builtin 'system.locals' implemented as a plugin.
|
## The builtin 'system.locals' implemented as a plugin.
|
||||||
|
|
||||||
import plugins, ast, astalgo, magicsys, lookups, semdata, lowerings
|
import compiler/plugins, compiler/ast, compiler/astalgo, compiler/magicsys,
|
||||||
|
compiler/lookups, compiler/semdata, compiler/lowerings
|
||||||
|
|
||||||
proc semLocals(c: PContext, n: PNode): PNode =
|
proc semLocals(c: PContext, n: PNode): PNode =
|
||||||
var counter = 0
|
var counter = 0
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ const
|
||||||
wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern,
|
wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern,
|
||||||
wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wRaises,
|
wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wRaises,
|
||||||
wTags, wLocks, wGcSafe}
|
wTags, wLocks, wGcSafe}
|
||||||
exprPragmas* = {wLine, wLocks}
|
exprPragmas* = {wLine, wLocks, wNoRewrite}
|
||||||
stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangechecks,
|
stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangechecks,
|
||||||
wBoundchecks, wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints,
|
wBoundchecks, wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints,
|
||||||
wLinedir, wStacktrace, wLinetrace, wOptimization, wHint, wWarning, wError,
|
wLinedir, wStacktrace, wLinetrace, wOptimization, wHint, wWarning, wError,
|
||||||
|
|
@ -859,6 +859,8 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
|
||||||
c.module.flags.incl sfExperimental
|
c.module.flags.incl sfExperimental
|
||||||
else:
|
else:
|
||||||
localError(it.info, "'experimental' pragma only valid as toplevel statement")
|
localError(it.info, "'experimental' pragma only valid as toplevel statement")
|
||||||
|
of wNoRewrite:
|
||||||
|
noVal(it)
|
||||||
else: invalidPragma(it)
|
else: invalidPragma(it)
|
||||||
else: invalidPragma(it)
|
else: invalidPragma(it)
|
||||||
else: processNote(c, it)
|
else: processNote(c, it)
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,10 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
|
||||||
pickBest(callOp)
|
pickBest(callOp)
|
||||||
|
|
||||||
if overloadsState == csEmpty and result.state == csEmpty:
|
if overloadsState == csEmpty and result.state == csEmpty:
|
||||||
localError(n.info, errUndeclaredIdentifier, considerQuotedIdent(f).s)
|
if nfDotField in n.flags and nfExplicitCall notin n.flags:
|
||||||
|
localError(n.info, errUndeclaredField, considerQuotedIdent(f).s)
|
||||||
|
else:
|
||||||
|
localError(n.info, errUndeclaredRoutine, considerQuotedIdent(f).s)
|
||||||
return
|
return
|
||||||
elif result.state != csMatch:
|
elif result.state != csMatch:
|
||||||
if nfExprCall in n.flags:
|
if nfExprCall in n.flags:
|
||||||
|
|
|
||||||
|
|
@ -207,9 +207,9 @@ proc markGcUnsafe(a: PEffects; reason: PNode) =
|
||||||
a.owner.gcUnsafetyReason = newSym(skUnknown, getIdent("<unknown>"),
|
a.owner.gcUnsafetyReason = newSym(skUnknown, getIdent("<unknown>"),
|
||||||
a.owner, reason.info)
|
a.owner, reason.info)
|
||||||
|
|
||||||
proc listGcUnsafety(s: PSym; onlyWarning: bool) =
|
proc listGcUnsafety(s: PSym; onlyWarning: bool; cycleCheck: var IntSet) =
|
||||||
let u = s.gcUnsafetyReason
|
let u = s.gcUnsafetyReason
|
||||||
if u != nil:
|
if u != nil and not cycleCheck.containsOrIncl(u.id):
|
||||||
let msgKind = if onlyWarning: warnGcUnsafe2 else: errGenerated
|
let msgKind = if onlyWarning: warnGcUnsafe2 else: errGenerated
|
||||||
if u.kind in {skLet, skVar}:
|
if u.kind in {skLet, skVar}:
|
||||||
message(s.info, msgKind,
|
message(s.info, msgKind,
|
||||||
|
|
@ -218,7 +218,7 @@ proc listGcUnsafety(s: PSym; onlyWarning: bool) =
|
||||||
elif u.kind in routineKinds:
|
elif u.kind in routineKinds:
|
||||||
# recursive call *always* produces only a warning so the full error
|
# recursive call *always* produces only a warning so the full error
|
||||||
# message is printed:
|
# message is printed:
|
||||||
listGcUnsafety(u, true)
|
listGcUnsafety(u, true, cycleCheck)
|
||||||
message(s.info, msgKind,
|
message(s.info, msgKind,
|
||||||
"'$#' is not GC-safe as it calls '$#'" %
|
"'$#' is not GC-safe as it calls '$#'" %
|
||||||
[s.name.s, u.name.s])
|
[s.name.s, u.name.s])
|
||||||
|
|
@ -227,6 +227,10 @@ proc listGcUnsafety(s: PSym; onlyWarning: bool) =
|
||||||
message(u.info, msgKind,
|
message(u.info, msgKind,
|
||||||
"'$#' is not GC-safe as it performs an indirect call here" % s.name.s)
|
"'$#' is not GC-safe as it performs an indirect call here" % s.name.s)
|
||||||
|
|
||||||
|
proc listGcUnsafety(s: PSym; onlyWarning: bool) =
|
||||||
|
var cycleCheck = initIntSet()
|
||||||
|
listGcUnsafety(s, onlyWarning, cycleCheck)
|
||||||
|
|
||||||
proc useVar(a: PEffects, n: PNode) =
|
proc useVar(a: PEffects, n: PNode) =
|
||||||
let s = n.sym
|
let s = n.sym
|
||||||
if isLocalVar(a, s):
|
if isLocalVar(a, s):
|
||||||
|
|
|
||||||
|
|
@ -1268,6 +1268,8 @@ proc semPragmaBlock(c: PContext, n: PNode): PNode =
|
||||||
of wLocks:
|
of wLocks:
|
||||||
result = n
|
result = n
|
||||||
result.typ = n.sons[1].typ
|
result.typ = n.sons[1].typ
|
||||||
|
of wNoRewrite:
|
||||||
|
incl(result.flags, nfNoRewrite)
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
proc semStaticStmt(c: PContext, n: PNode): PNode =
|
proc semStaticStmt(c: PContext, n: PNode): PNode =
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ type
|
||||||
wFloatchecks, wNanChecks, wInfChecks,
|
wFloatchecks, wNanChecks, wInfChecks,
|
||||||
wAssertions, wPatterns, wWarnings,
|
wAssertions, wPatterns, wWarnings,
|
||||||
wHints, wOptimization, wRaises, wWrites, wReads, wSize, wEffects, wTags,
|
wHints, wOptimization, wRaises, wWrites, wReads, wSize, wEffects, wTags,
|
||||||
wDeadCodeElim, wSafecode, wNoForward,
|
wDeadCodeElim, wSafecode, wNoForward, wNoRewrite,
|
||||||
wPragma,
|
wPragma,
|
||||||
wCompileTime, wNoInit,
|
wCompileTime, wNoInit,
|
||||||
wPassc, wPassl, wBorrow, wDiscardable,
|
wPassc, wPassl, wBorrow, wDiscardable,
|
||||||
|
|
@ -139,7 +139,7 @@ const
|
||||||
|
|
||||||
"assertions", "patterns", "warnings", "hints",
|
"assertions", "patterns", "warnings", "hints",
|
||||||
"optimization", "raises", "writes", "reads", "size", "effects", "tags",
|
"optimization", "raises", "writes", "reads", "size", "effects", "tags",
|
||||||
"deadcodeelim", "safecode", "noforward",
|
"deadcodeelim", "safecode", "noforward", "norewrite",
|
||||||
"pragma",
|
"pragma",
|
||||||
"compiletime", "noinit",
|
"compiletime", "noinit",
|
||||||
"passc", "passl", "borrow", "discardable", "fieldchecks",
|
"passc", "passl", "borrow", "discardable", "fieldchecks",
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@
|
||||||
* `FloatInvalidOpError <system.html#FloatInvalidOpError>`_
|
* `FloatInvalidOpError <system.html#FloatInvalidOpError>`_
|
||||||
* `FloatOverflowError <system.html#FloatOverflowError>`_
|
* `FloatOverflowError <system.html#FloatOverflowError>`_
|
||||||
* `FloatUnderflowError <system.html#FloatUnderflowError>`_
|
* `FloatUnderflowError <system.html#FloatUnderflowError>`_
|
||||||
* `FieldError <system.html#InvalidFieldError>`_
|
* `FieldError <system.html#FieldError>`_
|
||||||
* `IndexError <system.html#InvalidIndexError>`_
|
* `IndexError <system.html#IndexError>`_
|
||||||
* `ObjectAssignmentError <system.html#ObjectAssignmentError>`_
|
* `ObjectAssignmentError <system.html#ObjectAssignmentError>`_
|
||||||
* `ObjectConversionError <system.html#ObjectConversionError>`_
|
* `ObjectConversionError <system.html#ObjectConversionError>`_
|
||||||
* `ValueError <system.html#ValueError>`_
|
* `ValueError <system.html#ValueError>`_
|
||||||
|
|
|
||||||
|
|
@ -340,6 +340,8 @@ proc `[]`*(x: Any, fieldName: string): Any =
|
||||||
if n != nil:
|
if n != nil:
|
||||||
result.value = x.value +!! n.offset
|
result.value = x.value +!! n.offset
|
||||||
result.rawType = n.typ
|
result.rawType = n.typ
|
||||||
|
elif x.rawType.kind == tyObject and x.rawType.base != nil:
|
||||||
|
return `[]`(TAny(value: x.value, rawType: x.rawType.base), fieldName)
|
||||||
else:
|
else:
|
||||||
raise newException(ValueError, "invalid field name: " & fieldName)
|
raise newException(ValueError, "invalid field name: " & fieldName)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ type
|
||||||
atEnd: bool
|
atEnd: bool
|
||||||
|
|
||||||
PZipFileStream* =
|
PZipFileStream* =
|
||||||
ref ZipFileStream ## a reader stream of a file within a zip archive
|
ref TZipFileStream ## a reader stream of a file within a zip archive
|
||||||
|
|
||||||
proc fsClose(s: Stream) = zip_fclose(PZipFileStream(s).f)
|
proc fsClose(s: Stream) = zip_fclose(PZipFileStream(s).f)
|
||||||
proc fsAtEnd(s: Stream): bool = PZipFileStream(s).atEnd
|
proc fsAtEnd(s: Stream): bool = PZipFileStream(s).atEnd
|
||||||
|
|
|
||||||
|
|
@ -99,16 +99,13 @@ proc lowerBound*[T](a: openArray[T], key: T, cmp: proc(x,y: T): int {.closure.})
|
||||||
## arr.insert(4, arr.lowerBound(4))
|
## arr.insert(4, arr.lowerBound(4))
|
||||||
## `after running the above arr is `[1,2,3,4,5,6,7,8,9]`
|
## `after running the above arr is `[1,2,3,4,5,6,7,8,9]`
|
||||||
result = a.low
|
result = a.low
|
||||||
var pos = result
|
var count = a.high - a.low + 1
|
||||||
var count, step: int
|
var step, pos: int
|
||||||
count = a.high - a.low + 1
|
|
||||||
while count != 0:
|
while count != 0:
|
||||||
pos = result
|
|
||||||
step = count div 2
|
step = count div 2
|
||||||
pos += step
|
pos = result + step
|
||||||
if cmp(a[pos], key) < 0:
|
if cmp(a[pos], key) < 0:
|
||||||
pos.inc
|
result = pos + 1
|
||||||
result = pos
|
|
||||||
count -= step + 1
|
count -= step + 1
|
||||||
else:
|
else:
|
||||||
count = step
|
count = step
|
||||||
|
|
@ -331,3 +328,16 @@ proc prevPermutation*[T](x: var openarray[T]): bool {.discardable.} =
|
||||||
swap x[i-1], x[j]
|
swap x[i-1], x[j]
|
||||||
|
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
|
when isMainModule:
|
||||||
|
# Tests for lowerBound
|
||||||
|
var arr = @[1,2,3,5,6,7,8,9]
|
||||||
|
assert arr.lowerBound(0) == 0
|
||||||
|
assert arr.lowerBound(4) == 3
|
||||||
|
assert arr.lowerBound(5) == 3
|
||||||
|
assert arr.lowerBound(10) == 8
|
||||||
|
arr = @[1,5,10]
|
||||||
|
assert arr.lowerBound(4) == 1
|
||||||
|
assert arr.lowerBound(5) == 1
|
||||||
|
assert arr.lowerBound(6) == 2
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -91,13 +91,13 @@ type
|
||||||
|
|
||||||
# TODO: Save AF, domain etc info and reuse it in procs which need it like connect.
|
# TODO: Save AF, domain etc info and reuse it in procs which need it like connect.
|
||||||
|
|
||||||
proc newAsyncSocket*(fd: AsyncFD, isBuff: bool): AsyncSocket =
|
proc newAsyncSocket*(fd: AsyncFD, buffered = true): AsyncSocket =
|
||||||
## Creates a new ``AsyncSocket`` based on the supplied params.
|
## Creates a new ``AsyncSocket`` based on the supplied params.
|
||||||
assert fd != osInvalidSocket.AsyncFD
|
assert fd != osInvalidSocket.AsyncFD
|
||||||
new(result)
|
new(result)
|
||||||
result.fd = fd.SocketHandle
|
result.fd = fd.SocketHandle
|
||||||
result.isBuffered = isBuff
|
result.isBuffered = buffered
|
||||||
if isBuff:
|
if buffered:
|
||||||
result.currPos = 0
|
result.currPos = 0
|
||||||
|
|
||||||
proc newAsyncSocket*(domain: Domain = AF_INET, typ: SockType = SOCK_STREAM,
|
proc newAsyncSocket*(domain: Domain = AF_INET, typ: SockType = SOCK_STREAM,
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
import winlean, os, strutils, math
|
import winlean, os, strutils, math
|
||||||
|
|
||||||
proc `-`(a, b: TFILETIME): int64 = a.rdFileTime - b.rdFileTime
|
proc `-`(a, b: FILETIME): int64 = a.rdFileTime - b.rdFileTime
|
||||||
elif defined(linux):
|
elif defined(linux):
|
||||||
from cpuinfo import countProcessors
|
from cpuinfo import countProcessors
|
||||||
|
|
||||||
|
|
@ -25,14 +25,14 @@ type
|
||||||
|
|
||||||
ThreadPoolState* = object
|
ThreadPoolState* = object
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
prevSysKernel, prevSysUser, prevProcKernel, prevProcUser: TFILETIME
|
prevSysKernel, prevSysUser, prevProcKernel, prevProcUser: FILETIME
|
||||||
calls*: int
|
calls*: int
|
||||||
|
|
||||||
proc advice*(s: var ThreadPoolState): ThreadPoolAdvice =
|
proc advice*(s: var ThreadPoolState): ThreadPoolAdvice =
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
var
|
var
|
||||||
sysIdle, sysKernel, sysUser,
|
sysIdle, sysKernel, sysUser,
|
||||||
procCreation, procExit, procKernel, procUser: TFILETIME
|
procCreation, procExit, procKernel, procUser: FILETIME
|
||||||
if getSystemTimes(sysIdle, sysKernel, sysUser) == 0 or
|
if getSystemTimes(sysIdle, sysKernel, sysUser) == 0 or
|
||||||
getProcessTimes(Handle(-1), procCreation, procExit,
|
getProcessTimes(Handle(-1), procCreation, procExit,
|
||||||
procKernel, procUser) == 0:
|
procKernel, procUser) == 0:
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ proc del*(monitor: FSMonitor, wd: cint) =
|
||||||
|
|
||||||
proc getEvent(m: FSMonitor, fd: cint): seq[MonitorEvent] =
|
proc getEvent(m: FSMonitor, fd: cint): seq[MonitorEvent] =
|
||||||
result = @[]
|
result = @[]
|
||||||
let size = (sizeof(TINotifyEvent)+2000)*MaxEvents
|
let size = (sizeof(INotifyEvent)+2000)*MaxEvents
|
||||||
var buffer = newString(size)
|
var buffer = newString(size)
|
||||||
|
|
||||||
let le = read(fd, addr(buffer[0]), size)
|
let le = read(fd, addr(buffer[0]), size)
|
||||||
|
|
@ -117,7 +117,7 @@ proc getEvent(m: FSMonitor, fd: cint): seq[MonitorEvent] =
|
||||||
|
|
||||||
var i = 0
|
var i = 0
|
||||||
while i < le:
|
while i < le:
|
||||||
var event = cast[ptr TINotifyEvent](addr(buffer[i]))
|
var event = cast[ptr INotifyEvent](addr(buffer[i]))
|
||||||
var mev: MonitorEvent
|
var mev: MonitorEvent
|
||||||
mev.wd = event.wd
|
mev.wd = event.wd
|
||||||
if event.len.int != 0:
|
if event.len.int != 0:
|
||||||
|
|
@ -129,7 +129,7 @@ proc getEvent(m: FSMonitor, fd: cint): seq[MonitorEvent] =
|
||||||
if (event.mask.int and IN_MOVED_FROM) != 0:
|
if (event.mask.int and IN_MOVED_FROM) != 0:
|
||||||
# Moved from event, add to m's collection
|
# Moved from event, add to m's collection
|
||||||
movedFrom.add(event.cookie.cint, (mev.wd, mev.name))
|
movedFrom.add(event.cookie.cint, (mev.wd, mev.name))
|
||||||
inc(i, sizeof(TINotifyEvent) + event.len.int)
|
inc(i, sizeof(INotifyEvent) + event.len.int)
|
||||||
continue
|
continue
|
||||||
elif (event.mask.int and IN_MOVED_TO) != 0:
|
elif (event.mask.int and IN_MOVED_TO) != 0:
|
||||||
mev.kind = MonitorMoved
|
mev.kind = MonitorMoved
|
||||||
|
|
@ -159,7 +159,7 @@ proc getEvent(m: FSMonitor, fd: cint): seq[MonitorEvent] =
|
||||||
mev.fullname = ""
|
mev.fullname = ""
|
||||||
|
|
||||||
result.add(mev)
|
result.add(mev)
|
||||||
inc(i, sizeof(TINotifyEvent) + event.len.int)
|
inc(i, sizeof(INotifyEvent) + event.len.int)
|
||||||
|
|
||||||
# If movedFrom events have not been matched with a moveTo. File has
|
# If movedFrom events have not been matched with a moveTo. File has
|
||||||
# been moved to an unwatched location, emit a MonitorDelete.
|
# been moved to an unwatched location, emit a MonitorDelete.
|
||||||
|
|
|
||||||
|
|
@ -119,13 +119,13 @@ proc toOSFlags*(socketFlags: set[SocketFlag]): cint =
|
||||||
result = result or MSG_PEEK
|
result = result or MSG_PEEK
|
||||||
of SocketFlag.SafeDisconn: continue
|
of SocketFlag.SafeDisconn: continue
|
||||||
|
|
||||||
proc newSocket(fd: SocketHandle, isBuff: bool): Socket =
|
proc newSocket*(fd: SocketHandle, buffered = true): Socket =
|
||||||
## Creates a new socket as specified by the params.
|
## Creates a new socket as specified by the params.
|
||||||
assert fd != osInvalidSocket
|
assert fd != osInvalidSocket
|
||||||
new(result)
|
new(result)
|
||||||
result.fd = fd
|
result.fd = fd
|
||||||
result.isBuffered = isBuff
|
result.isBuffered = buffered
|
||||||
if isBuff:
|
if buffered:
|
||||||
result.currPos = 0
|
result.currPos = 0
|
||||||
|
|
||||||
proc newSocket*(domain, typ, protocol: cint, buffered = true): Socket =
|
proc newSocket*(domain, typ, protocol: cint, buffered = true): Socket =
|
||||||
|
|
|
||||||
|
|
@ -1,698 +0,0 @@
|
||||||
#
|
|
||||||
#
|
|
||||||
# Nim's Runtime Library
|
|
||||||
# (c) Copyright 2015 Andreas Rumpf, Dominik Picheta
|
|
||||||
#
|
|
||||||
# See the file "copying.txt", included in this
|
|
||||||
# distribution, for details about the copyright.
|
|
||||||
#
|
|
||||||
|
|
||||||
import
|
|
||||||
hashes, strutils, lexbase, streams, unicode, macros
|
|
||||||
|
|
||||||
type
|
|
||||||
SexpEventKind* = enum ## enumeration of all events that may occur when parsing
|
|
||||||
sexpError, ## an error occurred during parsing
|
|
||||||
sexpEof, ## end of file reached
|
|
||||||
sexpString, ## a string literal
|
|
||||||
sexpSymbol, ## a symbol
|
|
||||||
sexpInt, ## an integer literal
|
|
||||||
sexpFloat, ## a float literal
|
|
||||||
sexpNil, ## the value ``nil``
|
|
||||||
sexpDot, ## the dot to separate car/cdr
|
|
||||||
sexpListStart, ## start of a list: the ``(`` token
|
|
||||||
sexpListEnd, ## end of a list: the ``)`` token
|
|
||||||
|
|
||||||
TokKind = enum # must be synchronized with SexpEventKind!
|
|
||||||
tkError,
|
|
||||||
tkEof,
|
|
||||||
tkString,
|
|
||||||
tkSymbol,
|
|
||||||
tkInt,
|
|
||||||
tkFloat,
|
|
||||||
tkNil,
|
|
||||||
tkDot,
|
|
||||||
tkParensLe,
|
|
||||||
tkParensRi
|
|
||||||
tkSpace
|
|
||||||
|
|
||||||
SexpError* = enum ## enumeration that lists all errors that can occur
|
|
||||||
errNone, ## no error
|
|
||||||
errInvalidToken, ## invalid token
|
|
||||||
errParensRiExpected, ## ``)`` expected
|
|
||||||
errQuoteExpected, ## ``"`` expected
|
|
||||||
errEofExpected, ## EOF expected
|
|
||||||
|
|
||||||
SexpParser* = object of BaseLexer ## the parser object.
|
|
||||||
a: string
|
|
||||||
tok: TokKind
|
|
||||||
kind: SexpEventKind
|
|
||||||
err: SexpError
|
|
||||||
{.deprecated: [TTokKind: TokKind].}
|
|
||||||
|
|
||||||
const
|
|
||||||
errorMessages: array [SexpError, string] = [
|
|
||||||
"no error",
|
|
||||||
"invalid token",
|
|
||||||
"')' expected",
|
|
||||||
"'\"' or \"'\" expected",
|
|
||||||
"EOF expected",
|
|
||||||
]
|
|
||||||
tokToStr: array [TokKind, string] = [
|
|
||||||
"invalid token",
|
|
||||||
"EOF",
|
|
||||||
"string literal",
|
|
||||||
"symbol",
|
|
||||||
"int literal",
|
|
||||||
"float literal",
|
|
||||||
"nil",
|
|
||||||
".",
|
|
||||||
"(", ")", "space"
|
|
||||||
]
|
|
||||||
|
|
||||||
proc close*(my: var SexpParser) {.inline.} =
|
|
||||||
## closes the parser `my` and its associated input stream.
|
|
||||||
lexbase.close(my)
|
|
||||||
|
|
||||||
proc str*(my: SexpParser): string {.inline.} =
|
|
||||||
## returns the character data for the events: ``sexpInt``, ``sexpFloat``,
|
|
||||||
## ``sexpString``
|
|
||||||
assert(my.kind in {sexpInt, sexpFloat, sexpString})
|
|
||||||
result = my.a
|
|
||||||
|
|
||||||
proc getInt*(my: SexpParser): BiggestInt {.inline.} =
|
|
||||||
## returns the number for the event: ``sexpInt``
|
|
||||||
assert(my.kind == sexpInt)
|
|
||||||
result = parseBiggestInt(my.a)
|
|
||||||
|
|
||||||
proc getFloat*(my: SexpParser): float {.inline.} =
|
|
||||||
## returns the number for the event: ``sexpFloat``
|
|
||||||
assert(my.kind == sexpFloat)
|
|
||||||
result = parseFloat(my.a)
|
|
||||||
|
|
||||||
proc kind*(my: SexpParser): SexpEventKind {.inline.} =
|
|
||||||
## returns the current event type for the SEXP parser
|
|
||||||
result = my.kind
|
|
||||||
|
|
||||||
proc getColumn*(my: SexpParser): int {.inline.} =
|
|
||||||
## get the current column the parser has arrived at.
|
|
||||||
result = getColNumber(my, my.bufpos)
|
|
||||||
|
|
||||||
proc getLine*(my: SexpParser): int {.inline.} =
|
|
||||||
## get the current line the parser has arrived at.
|
|
||||||
result = my.lineNumber
|
|
||||||
|
|
||||||
proc errorMsg*(my: SexpParser): string =
|
|
||||||
## returns a helpful error message for the event ``sexpError``
|
|
||||||
assert(my.kind == sexpError)
|
|
||||||
result = "($1, $2) Error: $3" % [$getLine(my), $getColumn(my), errorMessages[my.err]]
|
|
||||||
|
|
||||||
proc errorMsgExpected*(my: SexpParser, e: string): string =
|
|
||||||
## returns an error message "`e` expected" in the same format as the
|
|
||||||
## other error messages
|
|
||||||
result = "($1, $2) Error: $3" % [$getLine(my), $getColumn(my), e & " expected"]
|
|
||||||
|
|
||||||
proc handleHexChar(c: char, x: var int): bool =
|
|
||||||
result = true # Success
|
|
||||||
case c
|
|
||||||
of '0'..'9': x = (x shl 4) or (ord(c) - ord('0'))
|
|
||||||
of 'a'..'f': x = (x shl 4) or (ord(c) - ord('a') + 10)
|
|
||||||
of 'A'..'F': x = (x shl 4) or (ord(c) - ord('A') + 10)
|
|
||||||
else: result = false # error
|
|
||||||
|
|
||||||
proc parseString(my: var SexpParser): TokKind =
|
|
||||||
result = tkString
|
|
||||||
var pos = my.bufpos + 1
|
|
||||||
var buf = my.buf
|
|
||||||
while true:
|
|
||||||
case buf[pos]
|
|
||||||
of '\0':
|
|
||||||
my.err = errQuoteExpected
|
|
||||||
result = tkError
|
|
||||||
break
|
|
||||||
of '"':
|
|
||||||
inc(pos)
|
|
||||||
break
|
|
||||||
of '\\':
|
|
||||||
case buf[pos+1]
|
|
||||||
of '\\', '"', '\'', '/':
|
|
||||||
add(my.a, buf[pos+1])
|
|
||||||
inc(pos, 2)
|
|
||||||
of 'b':
|
|
||||||
add(my.a, '\b')
|
|
||||||
inc(pos, 2)
|
|
||||||
of 'f':
|
|
||||||
add(my.a, '\f')
|
|
||||||
inc(pos, 2)
|
|
||||||
of 'n':
|
|
||||||
add(my.a, '\L')
|
|
||||||
inc(pos, 2)
|
|
||||||
of 'r':
|
|
||||||
add(my.a, '\C')
|
|
||||||
inc(pos, 2)
|
|
||||||
of 't':
|
|
||||||
add(my.a, '\t')
|
|
||||||
inc(pos, 2)
|
|
||||||
of 'u':
|
|
||||||
inc(pos, 2)
|
|
||||||
var r: int
|
|
||||||
if handleHexChar(buf[pos], r): inc(pos)
|
|
||||||
if handleHexChar(buf[pos], r): inc(pos)
|
|
||||||
if handleHexChar(buf[pos], r): inc(pos)
|
|
||||||
if handleHexChar(buf[pos], r): inc(pos)
|
|
||||||
add(my.a, toUTF8(Rune(r)))
|
|
||||||
else:
|
|
||||||
# don't bother with the error
|
|
||||||
add(my.a, buf[pos])
|
|
||||||
inc(pos)
|
|
||||||
of '\c':
|
|
||||||
pos = lexbase.handleCR(my, pos)
|
|
||||||
buf = my.buf
|
|
||||||
add(my.a, '\c')
|
|
||||||
of '\L':
|
|
||||||
pos = lexbase.handleLF(my, pos)
|
|
||||||
buf = my.buf
|
|
||||||
add(my.a, '\L')
|
|
||||||
else:
|
|
||||||
add(my.a, buf[pos])
|
|
||||||
inc(pos)
|
|
||||||
my.bufpos = pos # store back
|
|
||||||
|
|
||||||
proc parseNumber(my: var SexpParser) =
|
|
||||||
var pos = my.bufpos
|
|
||||||
var buf = my.buf
|
|
||||||
if buf[pos] == '-':
|
|
||||||
add(my.a, '-')
|
|
||||||
inc(pos)
|
|
||||||
if buf[pos] == '.':
|
|
||||||
add(my.a, "0.")
|
|
||||||
inc(pos)
|
|
||||||
else:
|
|
||||||
while buf[pos] in Digits:
|
|
||||||
add(my.a, buf[pos])
|
|
||||||
inc(pos)
|
|
||||||
if buf[pos] == '.':
|
|
||||||
add(my.a, '.')
|
|
||||||
inc(pos)
|
|
||||||
# digits after the dot:
|
|
||||||
while buf[pos] in Digits:
|
|
||||||
add(my.a, buf[pos])
|
|
||||||
inc(pos)
|
|
||||||
if buf[pos] in {'E', 'e'}:
|
|
||||||
add(my.a, buf[pos])
|
|
||||||
inc(pos)
|
|
||||||
if buf[pos] in {'+', '-'}:
|
|
||||||
add(my.a, buf[pos])
|
|
||||||
inc(pos)
|
|
||||||
while buf[pos] in Digits:
|
|
||||||
add(my.a, buf[pos])
|
|
||||||
inc(pos)
|
|
||||||
my.bufpos = pos
|
|
||||||
|
|
||||||
proc parseSymbol(my: var SexpParser) =
|
|
||||||
var pos = my.bufpos
|
|
||||||
var buf = my.buf
|
|
||||||
if buf[pos] in IdentStartChars:
|
|
||||||
while buf[pos] in IdentChars:
|
|
||||||
add(my.a, buf[pos])
|
|
||||||
inc(pos)
|
|
||||||
my.bufpos = pos
|
|
||||||
|
|
||||||
proc getTok(my: var SexpParser): TokKind =
|
|
||||||
setLen(my.a, 0)
|
|
||||||
case my.buf[my.bufpos]
|
|
||||||
of '-', '0'..'9': # numbers that start with a . are not parsed
|
|
||||||
# correctly.
|
|
||||||
parseNumber(my)
|
|
||||||
if {'.', 'e', 'E'} in my.a:
|
|
||||||
result = tkFloat
|
|
||||||
else:
|
|
||||||
result = tkInt
|
|
||||||
of '"': #" # gotta fix nim-mode
|
|
||||||
result = parseString(my)
|
|
||||||
of '(':
|
|
||||||
inc(my.bufpos)
|
|
||||||
result = tkParensLe
|
|
||||||
of ')':
|
|
||||||
inc(my.bufpos)
|
|
||||||
result = tkParensRi
|
|
||||||
of '\0':
|
|
||||||
result = tkEof
|
|
||||||
of 'a'..'z', 'A'..'Z', '_':
|
|
||||||
parseSymbol(my)
|
|
||||||
if my.a == "nil":
|
|
||||||
result = tkNil
|
|
||||||
else:
|
|
||||||
result = tkSymbol
|
|
||||||
of ' ':
|
|
||||||
result = tkSpace
|
|
||||||
inc(my.bufpos)
|
|
||||||
of '.':
|
|
||||||
result = tkDot
|
|
||||||
inc(my.bufpos)
|
|
||||||
else:
|
|
||||||
inc(my.bufpos)
|
|
||||||
result = tkError
|
|
||||||
my.tok = result
|
|
||||||
|
|
||||||
# ------------- higher level interface ---------------------------------------
|
|
||||||
|
|
||||||
type
|
|
||||||
SexpNodeKind* = enum ## possible SEXP node types
|
|
||||||
SNil,
|
|
||||||
SInt,
|
|
||||||
SFloat,
|
|
||||||
SString,
|
|
||||||
SSymbol,
|
|
||||||
SList,
|
|
||||||
SCons
|
|
||||||
|
|
||||||
SexpNode* = ref SexpNodeObj ## SEXP node
|
|
||||||
SexpNodeObj* {.acyclic.} = object
|
|
||||||
case kind*: SexpNodeKind
|
|
||||||
of SString:
|
|
||||||
str*: string
|
|
||||||
of SSymbol:
|
|
||||||
symbol*: string
|
|
||||||
of SInt:
|
|
||||||
num*: BiggestInt
|
|
||||||
of SFloat:
|
|
||||||
fnum*: float
|
|
||||||
of SList:
|
|
||||||
elems*: seq[SexpNode]
|
|
||||||
of SCons:
|
|
||||||
car: SexpNode
|
|
||||||
cdr: SexpNode
|
|
||||||
of SNil:
|
|
||||||
discard
|
|
||||||
|
|
||||||
Cons = tuple[car: SexpNode, cdr: SexpNode]
|
|
||||||
|
|
||||||
SexpParsingError* = object of ValueError ## is raised for a SEXP error
|
|
||||||
|
|
||||||
proc raiseParseErr*(p: SexpParser, msg: string) {.noinline, noreturn.} =
|
|
||||||
## raises an `ESexpParsingError` exception.
|
|
||||||
raise newException(SexpParsingError, errorMsgExpected(p, msg))
|
|
||||||
|
|
||||||
proc newSString*(s: string): SexpNode {.procvar.}=
|
|
||||||
## Creates a new `SString SexpNode`.
|
|
||||||
new(result)
|
|
||||||
result.kind = SString
|
|
||||||
result.str = s
|
|
||||||
|
|
||||||
proc newSStringMove(s: string): SexpNode =
|
|
||||||
new(result)
|
|
||||||
result.kind = SString
|
|
||||||
shallowCopy(result.str, s)
|
|
||||||
|
|
||||||
proc newSInt*(n: BiggestInt): SexpNode {.procvar.} =
|
|
||||||
## Creates a new `SInt SexpNode`.
|
|
||||||
new(result)
|
|
||||||
result.kind = SInt
|
|
||||||
result.num = n
|
|
||||||
|
|
||||||
proc newSFloat*(n: float): SexpNode {.procvar.} =
|
|
||||||
## Creates a new `SFloat SexpNode`.
|
|
||||||
new(result)
|
|
||||||
result.kind = SFloat
|
|
||||||
result.fnum = n
|
|
||||||
|
|
||||||
proc newSNil*(): SexpNode {.procvar.} =
|
|
||||||
## Creates a new `SNil SexpNode`.
|
|
||||||
new(result)
|
|
||||||
|
|
||||||
proc newSCons*(car, cdr: SexpNode): SexpNode {.procvar.} =
|
|
||||||
## Creates a new `SCons SexpNode`
|
|
||||||
new(result)
|
|
||||||
result.kind = SCons
|
|
||||||
result.car = car
|
|
||||||
result.cdr = cdr
|
|
||||||
|
|
||||||
proc newSList*(): SexpNode {.procvar.} =
|
|
||||||
## Creates a new `SList SexpNode`
|
|
||||||
new(result)
|
|
||||||
result.kind = SList
|
|
||||||
result.elems = @[]
|
|
||||||
|
|
||||||
proc newSSymbol*(s: string): SexpNode {.procvar.} =
|
|
||||||
new(result)
|
|
||||||
result.kind = SSymbol
|
|
||||||
result.symbol = s
|
|
||||||
|
|
||||||
proc newSSymbolMove(s: string): SexpNode =
|
|
||||||
new(result)
|
|
||||||
result.kind = SSymbol
|
|
||||||
shallowCopy(result.symbol, s)
|
|
||||||
|
|
||||||
proc getStr*(n: SexpNode, default: string = ""): string =
|
|
||||||
## Retrieves the string value of a `SString SexpNode`.
|
|
||||||
##
|
|
||||||
## Returns ``default`` if ``n`` is not a ``SString``.
|
|
||||||
if n.kind != SString: return default
|
|
||||||
else: return n.str
|
|
||||||
|
|
||||||
proc getNum*(n: SexpNode, default: BiggestInt = 0): BiggestInt =
|
|
||||||
## Retrieves the int value of a `SInt SexpNode`.
|
|
||||||
##
|
|
||||||
## Returns ``default`` if ``n`` is not a ``SInt``.
|
|
||||||
if n.kind != SInt: return default
|
|
||||||
else: return n.num
|
|
||||||
|
|
||||||
proc getFNum*(n: SexpNode, default: float = 0.0): float =
|
|
||||||
## Retrieves the float value of a `SFloat SexpNode`.
|
|
||||||
##
|
|
||||||
## Returns ``default`` if ``n`` is not a ``SFloat``.
|
|
||||||
if n.kind != SFloat: return default
|
|
||||||
else: return n.fnum
|
|
||||||
|
|
||||||
proc getSymbol*(n: SexpNode, default: string = ""): string =
|
|
||||||
## Retrieves the int value of a `SList SexpNode`.
|
|
||||||
##
|
|
||||||
## Returns ``default`` if ``n`` is not a ``SList``.
|
|
||||||
if n.kind != SSymbol: return default
|
|
||||||
else: return n.symbol
|
|
||||||
|
|
||||||
proc getElems*(n: SexpNode, default: seq[SexpNode] = @[]): seq[SexpNode] =
|
|
||||||
## Retrieves the int value of a `SList SexpNode`.
|
|
||||||
##
|
|
||||||
## Returns ``default`` if ``n`` is not a ``SList``.
|
|
||||||
if n.kind == SNil: return @[]
|
|
||||||
elif n.kind != SList: return default
|
|
||||||
else: return n.elems
|
|
||||||
|
|
||||||
proc getCons*(n: SexpNode, defaults: Cons = (newSNil(), newSNil())): Cons =
|
|
||||||
## Retrieves the cons value of a `SList SexpNode`.
|
|
||||||
##
|
|
||||||
## Returns ``default`` if ``n`` is not a ``SList``.
|
|
||||||
if n.kind == SCons: return (n.car, n.cdr)
|
|
||||||
elif n.kind == SList: return (n.elems[0], n.elems[1])
|
|
||||||
else: return defaults
|
|
||||||
|
|
||||||
proc sexp*(s: string): SexpNode =
|
|
||||||
## Generic constructor for SEXP data. Creates a new `SString SexpNode`.
|
|
||||||
new(result)
|
|
||||||
result.kind = SString
|
|
||||||
result.str = s
|
|
||||||
|
|
||||||
proc sexp*(n: BiggestInt): SexpNode =
|
|
||||||
## Generic constructor for SEXP data. Creates a new `SInt SexpNode`.
|
|
||||||
new(result)
|
|
||||||
result.kind = SInt
|
|
||||||
result.num = n
|
|
||||||
|
|
||||||
proc sexp*(n: float): SexpNode =
|
|
||||||
## Generic constructor for SEXP data. Creates a new `SFloat SexpNode`.
|
|
||||||
new(result)
|
|
||||||
result.kind = SFloat
|
|
||||||
result.fnum = n
|
|
||||||
|
|
||||||
proc sexp*(b: bool): SexpNode =
|
|
||||||
## Generic constructor for SEXP data. Creates a new `SSymbol
|
|
||||||
## SexpNode` with value t or `SNil SexpNode`.
|
|
||||||
new(result)
|
|
||||||
if b:
|
|
||||||
result.kind = SSymbol
|
|
||||||
result.symbol = "t"
|
|
||||||
else:
|
|
||||||
result.kind = SNil
|
|
||||||
|
|
||||||
proc sexp*(elements: openArray[SexpNode]): SexpNode =
|
|
||||||
## Generic constructor for SEXP data. Creates a new `SList SexpNode`
|
|
||||||
new(result)
|
|
||||||
result.kind = SList
|
|
||||||
newSeq(result.elems, elements.len)
|
|
||||||
for i, p in pairs(elements): result.elems[i] = p
|
|
||||||
|
|
||||||
proc sexp*(s: SexpNode): SexpNode =
|
|
||||||
result = s
|
|
||||||
|
|
||||||
proc toSexp(x: NimNode): NimNode {.compiletime.} =
|
|
||||||
case x.kind
|
|
||||||
of nnkBracket:
|
|
||||||
result = newNimNode(nnkBracket)
|
|
||||||
for i in 0 .. <x.len:
|
|
||||||
result.add(toSexp(x[i]))
|
|
||||||
|
|
||||||
else:
|
|
||||||
result = x
|
|
||||||
|
|
||||||
result = prefix(result, "sexp")
|
|
||||||
|
|
||||||
macro convertSexp*(x: expr): expr =
|
|
||||||
## Convert an expression to a SexpNode directly, without having to specify
|
|
||||||
## `%` for every element.
|
|
||||||
result = toSexp(x)
|
|
||||||
|
|
||||||
proc `==`* (a,b: SexpNode): bool =
|
|
||||||
## Check two nodes for equality
|
|
||||||
if a.isNil:
|
|
||||||
if b.isNil: return true
|
|
||||||
return false
|
|
||||||
elif b.isNil or a.kind != b.kind:
|
|
||||||
return false
|
|
||||||
else:
|
|
||||||
return case a.kind
|
|
||||||
of SString:
|
|
||||||
a.str == b.str
|
|
||||||
of SInt:
|
|
||||||
a.num == b.num
|
|
||||||
of SFloat:
|
|
||||||
a.fnum == b.fnum
|
|
||||||
of SNil:
|
|
||||||
true
|
|
||||||
of SList:
|
|
||||||
a.elems == b.elems
|
|
||||||
of SSymbol:
|
|
||||||
a.symbol == b.symbol
|
|
||||||
of SCons:
|
|
||||||
a.car == b.car and a.cdr == b.cdr
|
|
||||||
|
|
||||||
proc hash* (n:SexpNode): Hash =
|
|
||||||
## Compute the hash for a SEXP node
|
|
||||||
case n.kind
|
|
||||||
of SList:
|
|
||||||
result = hash(n.elems)
|
|
||||||
of SInt:
|
|
||||||
result = hash(n.num)
|
|
||||||
of SFloat:
|
|
||||||
result = hash(n.fnum)
|
|
||||||
of SString:
|
|
||||||
result = hash(n.str)
|
|
||||||
of SNil:
|
|
||||||
result = hash(0)
|
|
||||||
of SSymbol:
|
|
||||||
result = hash(n.symbol)
|
|
||||||
of SCons:
|
|
||||||
result = hash(n.car) !& hash(n.cdr)
|
|
||||||
|
|
||||||
proc len*(n: SexpNode): int =
|
|
||||||
## If `n` is a `SList`, it returns the number of elements.
|
|
||||||
## If `n` is a `JObject`, it returns the number of pairs.
|
|
||||||
## Else it returns 0.
|
|
||||||
case n.kind
|
|
||||||
of SList: result = n.elems.len
|
|
||||||
else: discard
|
|
||||||
|
|
||||||
proc `[]`*(node: SexpNode, index: int): SexpNode =
|
|
||||||
## Gets the node at `index` in a List. Result is undefined if `index`
|
|
||||||
## is out of bounds
|
|
||||||
assert(not isNil(node))
|
|
||||||
assert(node.kind == SList)
|
|
||||||
return node.elems[index]
|
|
||||||
|
|
||||||
proc add*(father, child: SexpNode) =
|
|
||||||
## Adds `child` to a SList node `father`.
|
|
||||||
assert father.kind == SList
|
|
||||||
father.elems.add(child)
|
|
||||||
|
|
||||||
# ------------- pretty printing ----------------------------------------------
|
|
||||||
|
|
||||||
proc indent(s: var string, i: int) =
|
|
||||||
s.add(spaces(i))
|
|
||||||
|
|
||||||
proc newIndent(curr, indent: int, ml: bool): int =
|
|
||||||
if ml: return curr + indent
|
|
||||||
else: return indent
|
|
||||||
|
|
||||||
proc nl(s: var string, ml: bool) =
|
|
||||||
if ml: s.add("\n")
|
|
||||||
|
|
||||||
proc escapeJson*(s: string): string =
|
|
||||||
## Converts a string `s` to its JSON representation.
|
|
||||||
result = newStringOfCap(s.len + s.len shr 3)
|
|
||||||
result.add("\"")
|
|
||||||
for x in runes(s):
|
|
||||||
var r = int(x)
|
|
||||||
if r >= 32 and r <= 127:
|
|
||||||
var c = chr(r)
|
|
||||||
case c
|
|
||||||
of '"': result.add("\\\"") #" # gotta fix nim-mode
|
|
||||||
of '\\': result.add("\\\\")
|
|
||||||
else: result.add(c)
|
|
||||||
else:
|
|
||||||
result.add("\\u")
|
|
||||||
result.add(toHex(r, 4))
|
|
||||||
result.add("\"")
|
|
||||||
|
|
||||||
proc copy*(p: SexpNode): SexpNode =
|
|
||||||
## Performs a deep copy of `a`.
|
|
||||||
case p.kind
|
|
||||||
of SString:
|
|
||||||
result = newSString(p.str)
|
|
||||||
of SInt:
|
|
||||||
result = newSInt(p.num)
|
|
||||||
of SFloat:
|
|
||||||
result = newSFloat(p.fnum)
|
|
||||||
of SNil:
|
|
||||||
result = newSNil()
|
|
||||||
of SSymbol:
|
|
||||||
result = newSSymbol(p.symbol)
|
|
||||||
of SList:
|
|
||||||
result = newSList()
|
|
||||||
for i in items(p.elems):
|
|
||||||
result.elems.add(copy(i))
|
|
||||||
of SCons:
|
|
||||||
result = newSCons(copy(p.car), copy(p.cdr))
|
|
||||||
|
|
||||||
proc toPretty(result: var string, node: SexpNode, indent = 2, ml = true,
|
|
||||||
lstArr = false, currIndent = 0) =
|
|
||||||
case node.kind
|
|
||||||
of SString:
|
|
||||||
if lstArr: result.indent(currIndent)
|
|
||||||
result.add(escapeJson(node.str))
|
|
||||||
of SInt:
|
|
||||||
if lstArr: result.indent(currIndent)
|
|
||||||
result.add($node.num)
|
|
||||||
of SFloat:
|
|
||||||
if lstArr: result.indent(currIndent)
|
|
||||||
result.add($node.fnum)
|
|
||||||
of SNil:
|
|
||||||
if lstArr: result.indent(currIndent)
|
|
||||||
result.add("nil")
|
|
||||||
of SSymbol:
|
|
||||||
if lstArr: result.indent(currIndent)
|
|
||||||
result.add($node.symbol)
|
|
||||||
of SList:
|
|
||||||
if lstArr: result.indent(currIndent)
|
|
||||||
if len(node.elems) != 0:
|
|
||||||
result.add("(")
|
|
||||||
result.nl(ml)
|
|
||||||
for i in 0..len(node.elems)-1:
|
|
||||||
if i > 0:
|
|
||||||
result.add(" ")
|
|
||||||
result.nl(ml) # New Line
|
|
||||||
toPretty(result, node.elems[i], indent, ml,
|
|
||||||
true, newIndent(currIndent, indent, ml))
|
|
||||||
result.nl(ml)
|
|
||||||
result.indent(currIndent)
|
|
||||||
result.add(")")
|
|
||||||
else: result.add("nil")
|
|
||||||
of SCons:
|
|
||||||
if lstArr: result.indent(currIndent)
|
|
||||||
result.add("(")
|
|
||||||
toPretty(result, node.car, indent, ml,
|
|
||||||
true, newIndent(currIndent, indent, ml))
|
|
||||||
result.add(" . ")
|
|
||||||
toPretty(result, node.cdr, indent, ml,
|
|
||||||
true, newIndent(currIndent, indent, ml))
|
|
||||||
result.add(")")
|
|
||||||
|
|
||||||
proc pretty*(node: SexpNode, indent = 2): string =
|
|
||||||
## Converts `node` to its Sexp Representation, with indentation and
|
|
||||||
## on multiple lines.
|
|
||||||
result = ""
|
|
||||||
toPretty(result, node, indent)
|
|
||||||
|
|
||||||
proc `$`*(node: SexpNode): string =
|
|
||||||
## Converts `node` to its SEXP Representation on one line.
|
|
||||||
result = ""
|
|
||||||
toPretty(result, node, 0, false)
|
|
||||||
|
|
||||||
iterator items*(node: SexpNode): SexpNode =
|
|
||||||
## Iterator for the items of `node`. `node` has to be a SList.
|
|
||||||
assert node.kind == SList
|
|
||||||
for i in items(node.elems):
|
|
||||||
yield i
|
|
||||||
|
|
||||||
iterator mitems*(node: var SexpNode): var SexpNode =
|
|
||||||
## Iterator for the items of `node`. `node` has to be a SList. Items can be
|
|
||||||
## modified.
|
|
||||||
assert node.kind == SList
|
|
||||||
for i in mitems(node.elems):
|
|
||||||
yield i
|
|
||||||
|
|
||||||
proc eat(p: var SexpParser, tok: TokKind) =
|
|
||||||
if p.tok == tok: discard getTok(p)
|
|
||||||
else: raiseParseErr(p, tokToStr[tok])
|
|
||||||
|
|
||||||
proc parseSexp(p: var SexpParser): SexpNode =
|
|
||||||
## Parses SEXP from a SEXP Parser `p`.
|
|
||||||
case p.tok
|
|
||||||
of tkString:
|
|
||||||
# we capture 'p.a' here, so we need to give it a fresh buffer afterwards:
|
|
||||||
result = newSStringMove(p.a)
|
|
||||||
p.a = ""
|
|
||||||
discard getTok(p)
|
|
||||||
of tkInt:
|
|
||||||
result = newSInt(parseBiggestInt(p.a))
|
|
||||||
discard getTok(p)
|
|
||||||
of tkFloat:
|
|
||||||
result = newSFloat(parseFloat(p.a))
|
|
||||||
discard getTok(p)
|
|
||||||
of tkNil:
|
|
||||||
result = newSNil()
|
|
||||||
discard getTok(p)
|
|
||||||
of tkSymbol:
|
|
||||||
result = newSSymbolMove(p.a)
|
|
||||||
p.a = ""
|
|
||||||
discard getTok(p)
|
|
||||||
of tkParensLe:
|
|
||||||
result = newSList()
|
|
||||||
discard getTok(p)
|
|
||||||
while p.tok notin {tkParensRi, tkDot}:
|
|
||||||
result.add(parseSexp(p))
|
|
||||||
if p.tok != tkSpace: break
|
|
||||||
discard getTok(p)
|
|
||||||
if p.tok == tkDot:
|
|
||||||
eat(p, tkDot)
|
|
||||||
eat(p, tkSpace)
|
|
||||||
result.add(parseSexp(p))
|
|
||||||
result = newSCons(result[0], result[1])
|
|
||||||
eat(p, tkParensRi)
|
|
||||||
of tkSpace, tkDot, tkError, tkParensRi, tkEof:
|
|
||||||
raiseParseErr(p, "(")
|
|
||||||
|
|
||||||
proc open*(my: var SexpParser, input: Stream) =
|
|
||||||
## initializes the parser with an input stream.
|
|
||||||
lexbase.open(my, input)
|
|
||||||
my.kind = sexpError
|
|
||||||
my.a = ""
|
|
||||||
|
|
||||||
proc parseSexp*(s: Stream): SexpNode =
|
|
||||||
## Parses from a buffer `s` into a `SexpNode`.
|
|
||||||
var p: SexpParser
|
|
||||||
p.open(s)
|
|
||||||
discard getTok(p) # read first token
|
|
||||||
result = p.parseSexp()
|
|
||||||
p.close()
|
|
||||||
|
|
||||||
proc parseSexp*(buffer: string): SexpNode =
|
|
||||||
## Parses Sexp from `buffer`.
|
|
||||||
result = parseSexp(newStringStream(buffer))
|
|
||||||
|
|
||||||
when isMainModule:
|
|
||||||
let testSexp = parseSexp("""(1 (98 2) nil (2) foobar "foo" 9.234)""")
|
|
||||||
assert(testSexp[0].getNum == 1)
|
|
||||||
assert(testSexp[1][0].getNum == 98)
|
|
||||||
assert(testSexp[2].getElems == @[])
|
|
||||||
assert(testSexp[4].getSymbol == "foobar")
|
|
||||||
assert(testSexp[5].getStr == "foo")
|
|
||||||
|
|
||||||
let alist = parseSexp("""((1 . 2) (2 . "foo"))""")
|
|
||||||
assert(alist[0].getCons.car.getNum == 1)
|
|
||||||
assert(alist[0].getCons.cdr.getNum == 2)
|
|
||||||
assert(alist[1].getCons.cdr.getStr == "foo")
|
|
||||||
|
|
||||||
# Generator:
|
|
||||||
var j = convertSexp([true, false, "foobar", [1, 2, "baz"]])
|
|
||||||
assert($j == """(t nil "foobar" (1 2 "baz"))""")
|
|
||||||
|
|
@ -99,6 +99,7 @@ template test*(name: expr, body: stmt): stmt {.immediate, dirty.} =
|
||||||
body
|
body
|
||||||
|
|
||||||
except:
|
except:
|
||||||
|
when not defined(js):
|
||||||
checkpoint("Unhandled exception: " & getCurrentExceptionMsg())
|
checkpoint("Unhandled exception: " & getCurrentExceptionMsg())
|
||||||
echo getCurrentException().getStackTrace()
|
echo getCurrentException().getStackTrace()
|
||||||
fail()
|
fail()
|
||||||
|
|
@ -114,9 +115,7 @@ proc checkpoint*(msg: string) =
|
||||||
template fail* =
|
template fail* =
|
||||||
bind checkpoints
|
bind checkpoints
|
||||||
for msg in items(checkpoints):
|
for msg in items(checkpoints):
|
||||||
# this used to be 'echo' which now breaks due to a bug. XXX will revisit
|
echo msg
|
||||||
# this issue later.
|
|
||||||
stdout.writeln msg
|
|
||||||
|
|
||||||
when not defined(ECMAScript):
|
when not defined(ECMAScript):
|
||||||
if abortOnError: quit(1)
|
if abortOnError: quit(1)
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,60 @@ proc raiseOverflow {.compilerproc, noinline.} =
|
||||||
proc raiseDivByZero {.compilerproc, noinline.} =
|
proc raiseDivByZero {.compilerproc, noinline.} =
|
||||||
sysFatal(DivByZeroError, "division by zero")
|
sysFatal(DivByZeroError, "division by zero")
|
||||||
|
|
||||||
|
when defined(builtinOverflow):
|
||||||
|
# Builtin compiler functions for improved performance
|
||||||
|
when sizeof(clong) == 8:
|
||||||
|
proc addInt64Overflow[T: int64|int](a, b: T, c: var T): bool {.
|
||||||
|
importc: "__builtin_saddl_overflow", nodecl, nosideeffect.}
|
||||||
|
|
||||||
|
proc subInt64Overflow[T: int64|int](a, b: T, c: var T): bool {.
|
||||||
|
importc: "__builtin_ssubl_overflow", nodecl, nosideeffect.}
|
||||||
|
|
||||||
|
proc mulInt64Overflow[T: int64|int](a, b: T, c: var T): bool {.
|
||||||
|
importc: "__builtin_smull_overflow", nodecl, nosideeffect.}
|
||||||
|
|
||||||
|
elif sizeof(clonglong) == 8:
|
||||||
|
proc addInt64Overflow[T: int64|int](a, b: T, c: var T): bool {.
|
||||||
|
importc: "__builtin_saddll_overflow", nodecl, nosideeffect.}
|
||||||
|
|
||||||
|
proc subInt64Overflow[T: int64|int](a, b: T, c: var T): bool {.
|
||||||
|
importc: "__builtin_ssubll_overflow", nodecl, nosideeffect.}
|
||||||
|
|
||||||
|
proc mulInt64Overflow[T: int64|int](a, b: T, c: var T): bool {.
|
||||||
|
importc: "__builtin_smulll_overflow", nodecl, nosideeffect.}
|
||||||
|
|
||||||
|
when sizeof(int) == 8:
|
||||||
|
proc addIntOverflow(a, b: int, c: var int): bool {.inline.} =
|
||||||
|
addInt64Overflow(a, b, c)
|
||||||
|
|
||||||
|
proc subIntOverflow(a, b: int, c: var int): bool {.inline.} =
|
||||||
|
subInt64Overflow(a, b, c)
|
||||||
|
|
||||||
|
proc mulIntOverflow(a, b: int, c: var int): bool {.inline.} =
|
||||||
|
mulInt64Overflow(a, b, c)
|
||||||
|
|
||||||
|
elif sizeof(int) == 4 and sizeof(cint) == 4:
|
||||||
|
proc addIntOverflow(a, b: int, c: var int): bool {.
|
||||||
|
importc: "__builtin_sadd_overflow", nodecl, nosideeffect.}
|
||||||
|
|
||||||
|
proc subIntOverflow(a, b: int, c: var int): bool {.
|
||||||
|
importc: "__builtin_ssub_overflow", nodecl, nosideeffect.}
|
||||||
|
|
||||||
|
proc mulIntOverflow(a, b: int, c: var int): bool {.
|
||||||
|
importc: "__builtin_smul_overflow", nodecl, nosideeffect.}
|
||||||
|
|
||||||
|
proc addInt64(a, b: int64): int64 {.compilerProc, inline.} =
|
||||||
|
if addInt64Overflow(a, b, result):
|
||||||
|
raiseOverflow()
|
||||||
|
|
||||||
|
proc subInt64(a, b: int64): int64 {.compilerProc, inline.} =
|
||||||
|
if subInt64Overflow(a, b, result):
|
||||||
|
raiseOverflow()
|
||||||
|
|
||||||
|
proc mulInt64(a, b: int64): int64 {.compilerproc, inline.} =
|
||||||
|
if mulInt64Overflow(a, b, result):
|
||||||
|
raiseOverflow()
|
||||||
|
else:
|
||||||
proc addInt64(a, b: int64): int64 {.compilerProc, inline.} =
|
proc addInt64(a, b: int64): int64 {.compilerProc, inline.} =
|
||||||
result = a +% b
|
result = a +% b
|
||||||
if (result xor a) >= int64(0) or (result xor b) >= int64(0):
|
if (result xor a) >= int64(0) or (result xor b) >= int64(0):
|
||||||
|
|
@ -29,28 +83,6 @@ proc subInt64(a, b: int64): int64 {.compilerProc, inline.} =
|
||||||
return result
|
return result
|
||||||
raiseOverflow()
|
raiseOverflow()
|
||||||
|
|
||||||
proc negInt64(a: int64): int64 {.compilerProc, inline.} =
|
|
||||||
if a != low(int64): return -a
|
|
||||||
raiseOverflow()
|
|
||||||
|
|
||||||
proc absInt64(a: int64): int64 {.compilerProc, inline.} =
|
|
||||||
if a != low(int64):
|
|
||||||
if a >= 0: return a
|
|
||||||
else: return -a
|
|
||||||
raiseOverflow()
|
|
||||||
|
|
||||||
proc divInt64(a, b: int64): int64 {.compilerProc, inline.} =
|
|
||||||
if b == int64(0):
|
|
||||||
raiseDivByZero()
|
|
||||||
if a == low(int64) and b == int64(-1):
|
|
||||||
raiseOverflow()
|
|
||||||
return a div b
|
|
||||||
|
|
||||||
proc modInt64(a, b: int64): int64 {.compilerProc, inline.} =
|
|
||||||
if b == int64(0):
|
|
||||||
raiseDivByZero()
|
|
||||||
return a mod b
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# This code has been inspired by Python's source code.
|
# This code has been inspired by Python's source code.
|
||||||
# The native int product x*y is either exactly right or *way* off, being
|
# The native int product x*y is either exactly right or *way* off, being
|
||||||
|
|
@ -94,6 +126,27 @@ proc mulInt64(a, b: int64): int64 {.compilerproc.} =
|
||||||
return result
|
return result
|
||||||
raiseOverflow()
|
raiseOverflow()
|
||||||
|
|
||||||
|
proc negInt64(a: int64): int64 {.compilerProc, inline.} =
|
||||||
|
if a != low(int64): return -a
|
||||||
|
raiseOverflow()
|
||||||
|
|
||||||
|
proc absInt64(a: int64): int64 {.compilerProc, inline.} =
|
||||||
|
if a != low(int64):
|
||||||
|
if a >= 0: return a
|
||||||
|
else: return -a
|
||||||
|
raiseOverflow()
|
||||||
|
|
||||||
|
proc divInt64(a, b: int64): int64 {.compilerProc, inline.} =
|
||||||
|
if b == int64(0):
|
||||||
|
raiseDivByZero()
|
||||||
|
if a == low(int64) and b == int64(-1):
|
||||||
|
raiseOverflow()
|
||||||
|
return a div b
|
||||||
|
|
||||||
|
proc modInt64(a, b: int64): int64 {.compilerProc, inline.} =
|
||||||
|
if b == int64(0):
|
||||||
|
raiseDivByZero()
|
||||||
|
return a mod b
|
||||||
|
|
||||||
proc absInt(a: int): int {.compilerProc, inline.} =
|
proc absInt(a: int): int {.compilerProc, inline.} =
|
||||||
if a != low(int):
|
if a != low(int):
|
||||||
|
|
@ -246,6 +299,21 @@ elif false: # asmVersion and (defined(gcc) or defined(llvm_gcc)):
|
||||||
:"%edx"
|
:"%edx"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
when not declared(addInt) and defined(builtinOverflow):
|
||||||
|
proc addInt(a, b: int): int {.compilerProc, inline.} =
|
||||||
|
if addIntOverflow(a, b, result):
|
||||||
|
raiseOverflow()
|
||||||
|
|
||||||
|
when not declared(subInt) and defined(builtinOverflow):
|
||||||
|
proc subInt(a, b: int): int {.compilerProc, inline.} =
|
||||||
|
if subIntOverflow(a, b, result):
|
||||||
|
raiseOverflow()
|
||||||
|
|
||||||
|
when not declared(mulInt) and defined(builtinOverflow):
|
||||||
|
proc mulInt(a, b: int): int {.compilerProc, inline.} =
|
||||||
|
if mulIntOverflow(a, b, result):
|
||||||
|
raiseOverflow()
|
||||||
|
|
||||||
# Platform independent versions of the above (slower!)
|
# Platform independent versions of the above (slower!)
|
||||||
when not declared(addInt):
|
when not declared(addInt):
|
||||||
proc addInt(a, b: int): int {.compilerProc, inline.} =
|
proc addInt(a, b: int): int {.compilerProc, inline.} =
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ type
|
||||||
stat: GcStat
|
stat: GcStat
|
||||||
additionalRoots: CellSeq # dummy roots for GC_ref/unref
|
additionalRoots: CellSeq # dummy roots for GC_ref/unref
|
||||||
{.deprecated: [TWalkOp: WalkOp, TFinalizer: Finalizer, TGcStat: GcStat,
|
{.deprecated: [TWalkOp: WalkOp, TFinalizer: Finalizer, TGcStat: GcStat,
|
||||||
TGlobalMarkerProc: GlobalMarkerProc, TGcHeap, GcHeap].}
|
TGlobalMarkerProc: GlobalMarkerProc, TGcHeap: GcHeap].}
|
||||||
var
|
var
|
||||||
gch {.rtlThreadVar.}: GcHeap
|
gch {.rtlThreadVar.}: GcHeap
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -690,6 +690,7 @@ const
|
||||||
ERROR_IO_PENDING* = 997 # a.k.a WSA_IO_PENDING
|
ERROR_IO_PENDING* = 997 # a.k.a WSA_IO_PENDING
|
||||||
FILE_FLAG_OVERLAPPED* = 1073741824
|
FILE_FLAG_OVERLAPPED* = 1073741824
|
||||||
WSAECONNABORTED* = 10053
|
WSAECONNABORTED* = 10053
|
||||||
|
WSAEADDRINUSE* = 10048
|
||||||
WSAECONNRESET* = 10054
|
WSAECONNRESET* = 10054
|
||||||
WSAEDISCON* = 10101
|
WSAEDISCON* = 10101
|
||||||
WSAENETRESET* = 10052
|
WSAENETRESET* = 10052
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ else:
|
||||||
type
|
type
|
||||||
Arg* = int
|
Arg* = int
|
||||||
SArg* = int
|
SArg* = int
|
||||||
{deprecated: [TArg: Arg, TSArg: SArg].}
|
{.deprecated: [TArg: Arg, TSArg: SArg].}
|
||||||
|
|
||||||
when defined(windows) and defined(x86):
|
when defined(windows) and defined(x86):
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ elif defined(macosx):
|
||||||
else:
|
else:
|
||||||
const
|
const
|
||||||
readlineDll* = "libreadline.so.6(|.0)"
|
readlineDll* = "libreadline.so.6(|.0)"
|
||||||
# mangle "'TCommandFunc'" TCommandFunc
|
# mangle "'CommandFunc'" CommandFunc
|
||||||
# mangle TvcpFunc TvcpFunc
|
# mangle TvcpFunc TvcpFunc
|
||||||
|
|
||||||
import rltypedefs
|
import rltypedefs
|
||||||
|
|
@ -80,7 +80,7 @@ const
|
||||||
type
|
type
|
||||||
KEYMAP_ENTRY*{.pure, final.} = object
|
KEYMAP_ENTRY*{.pure, final.} = object
|
||||||
typ*: char
|
typ*: char
|
||||||
function*: TCommandFunc
|
function*: CommandFunc
|
||||||
{.deprecated: [TKEYMAP_ENTRY: KEYMAP_ENTRY].}
|
{.deprecated: [TKEYMAP_ENTRY: KEYMAP_ENTRY].}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -243,7 +243,7 @@ when not defined(macosx):
|
||||||
type
|
type
|
||||||
FUNMAP*{.pure, final.} = object
|
FUNMAP*{.pure, final.} = object
|
||||||
name*: cstring
|
name*: cstring
|
||||||
function*: TCommandFunc
|
function*: CommandFunc
|
||||||
{.deprecated: [TFUNMAP: FUNMAP].}
|
{.deprecated: [TFUNMAP: FUNMAP].}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -610,31 +610,31 @@ proc discard_argument*(): cint{.cdecl, importc: "rl_discard_argument",
|
||||||
dynlib: readlineDll.}
|
dynlib: readlineDll.}
|
||||||
# Utility functions to bind keys to readline commands.
|
# Utility functions to bind keys to readline commands.
|
||||||
|
|
||||||
proc add_defun*(a2: cstring, a3: TCommandFunc, a4: cint): cint{.cdecl,
|
proc add_defun*(a2: cstring, a3: CommandFunc, a4: cint): cint{.cdecl,
|
||||||
importc: "rl_add_defun", dynlib: readlineDll.}
|
importc: "rl_add_defun", dynlib: readlineDll.}
|
||||||
proc bind_key*(a2: cint, a3: TCommandFunc): cint{.cdecl,
|
proc bind_key*(a2: cint, a3: CommandFunc): cint{.cdecl,
|
||||||
importc: "rl_bind_key", dynlib: readlineDll.}
|
importc: "rl_bind_key", dynlib: readlineDll.}
|
||||||
proc bind_key_in_map*(a2: cint, a3: TCommandFunc, a4: PKeymap): cint{.cdecl,
|
proc bind_key_in_map*(a2: cint, a3: CommandFunc, a4: PKeymap): cint{.cdecl,
|
||||||
importc: "rl_bind_key_in_map", dynlib: readlineDll.}
|
importc: "rl_bind_key_in_map", dynlib: readlineDll.}
|
||||||
proc unbind_key*(a2: cint): cint{.cdecl, importc: "rl_unbind_key",
|
proc unbind_key*(a2: cint): cint{.cdecl, importc: "rl_unbind_key",
|
||||||
dynlib: readlineDll.}
|
dynlib: readlineDll.}
|
||||||
proc unbind_key_in_map*(a2: cint, a3: PKeymap): cint{.cdecl,
|
proc unbind_key_in_map*(a2: cint, a3: PKeymap): cint{.cdecl,
|
||||||
importc: "rl_unbind_key_in_map", dynlib: readlineDll.}
|
importc: "rl_unbind_key_in_map", dynlib: readlineDll.}
|
||||||
proc bind_key_if_unbound*(a2: cint, a3: TCommandFunc): cint{.cdecl,
|
proc bind_key_if_unbound*(a2: cint, a3: CommandFunc): cint{.cdecl,
|
||||||
importc: "rl_bind_key_if_unbound", dynlib: readlineDll.}
|
importc: "rl_bind_key_if_unbound", dynlib: readlineDll.}
|
||||||
proc bind_key_if_unbound_in_map*(a2: cint, a3: TCommandFunc, a4: PKeymap): cint{.
|
proc bind_key_if_unbound_in_map*(a2: cint, a3: CommandFunc, a4: PKeymap): cint{.
|
||||||
cdecl, importc: "rl_bind_key_if_unbound_in_map", dynlib: readlineDll.}
|
cdecl, importc: "rl_bind_key_if_unbound_in_map", dynlib: readlineDll.}
|
||||||
proc unbind_function_in_map*(a2: TCommandFunc, a3: PKeymap): cint{.cdecl,
|
proc unbind_function_in_map*(a2: CommandFunc, a3: PKeymap): cint{.cdecl,
|
||||||
importc: "rl_unbind_function_in_map", dynlib: readlineDll.}
|
importc: "rl_unbind_function_in_map", dynlib: readlineDll.}
|
||||||
proc unbind_command_in_map*(a2: cstring, a3: PKeymap): cint{.cdecl,
|
proc unbind_command_in_map*(a2: cstring, a3: PKeymap): cint{.cdecl,
|
||||||
importc: "rl_unbind_command_in_map", dynlib: readlineDll.}
|
importc: "rl_unbind_command_in_map", dynlib: readlineDll.}
|
||||||
proc bind_keyseq*(a2: cstring, a3: TCommandFunc): cint{.cdecl,
|
proc bind_keyseq*(a2: cstring, a3: CommandFunc): cint{.cdecl,
|
||||||
importc: "rl_bind_keyseq", dynlib: readlineDll.}
|
importc: "rl_bind_keyseq", dynlib: readlineDll.}
|
||||||
proc bind_keyseq_in_map*(a2: cstring, a3: TCommandFunc, a4: PKeymap): cint{.
|
proc bind_keyseq_in_map*(a2: cstring, a3: CommandFunc, a4: PKeymap): cint{.
|
||||||
cdecl, importc: "rl_bind_keyseq_in_map", dynlib: readlineDll.}
|
cdecl, importc: "rl_bind_keyseq_in_map", dynlib: readlineDll.}
|
||||||
proc bind_keyseq_if_unbound*(a2: cstring, a3: TCommandFunc): cint{.cdecl,
|
proc bind_keyseq_if_unbound*(a2: cstring, a3: CommandFunc): cint{.cdecl,
|
||||||
importc: "rl_bind_keyseq_if_unbound", dynlib: readlineDll.}
|
importc: "rl_bind_keyseq_if_unbound", dynlib: readlineDll.}
|
||||||
proc bind_keyseq_if_unbound_in_map*(a2: cstring, a3: TCommandFunc,
|
proc bind_keyseq_if_unbound_in_map*(a2: cstring, a3: CommandFunc,
|
||||||
a4: PKeymap): cint{.cdecl,
|
a4: PKeymap): cint{.cdecl,
|
||||||
importc: "rl_bind_keyseq_if_unbound_in_map", dynlib: readlineDll.}
|
importc: "rl_bind_keyseq_if_unbound_in_map", dynlib: readlineDll.}
|
||||||
proc generic_bind*(a2: cint, a3: cstring, a4: cstring, a5: PKeymap): cint{.
|
proc generic_bind*(a2: cint, a3: cstring, a4: cstring, a5: PKeymap): cint{.
|
||||||
|
|
@ -645,7 +645,7 @@ proc variable_bind*(a2: cstring, a3: cstring): cint{.cdecl,
|
||||||
importc: "rl_variable_bind", dynlib: readlineDll.}
|
importc: "rl_variable_bind", dynlib: readlineDll.}
|
||||||
# Backwards compatibility, use rl_bind_keyseq_in_map instead.
|
# Backwards compatibility, use rl_bind_keyseq_in_map instead.
|
||||||
|
|
||||||
proc set_key*(a2: cstring, a3: TCommandFunc, a4: PKeymap): cint{.cdecl,
|
proc set_key*(a2: cstring, a3: CommandFunc, a4: PKeymap): cint{.cdecl,
|
||||||
importc: "rl_set_key", dynlib: readlineDll.}
|
importc: "rl_set_key", dynlib: readlineDll.}
|
||||||
# Backwards compatibility, use rl_generic_bind instead.
|
# Backwards compatibility, use rl_generic_bind instead.
|
||||||
|
|
||||||
|
|
@ -657,15 +657,15 @@ proc translate_keyseq*(a2: cstring, a3: cstring, a4: ptr cint): cint{.cdecl,
|
||||||
importc: "rl_translate_keyseq", dynlib: readlineDll.}
|
importc: "rl_translate_keyseq", dynlib: readlineDll.}
|
||||||
proc untranslate_keyseq*(a2: cint): cstring{.cdecl,
|
proc untranslate_keyseq*(a2: cint): cstring{.cdecl,
|
||||||
importc: "rl_untranslate_keyseq", dynlib: readlineDll.}
|
importc: "rl_untranslate_keyseq", dynlib: readlineDll.}
|
||||||
proc named_function*(a2: cstring): TCommandFunc{.cdecl,
|
proc named_function*(a2: cstring): CommandFunc{.cdecl,
|
||||||
importc: "rl_named_function", dynlib: readlineDll.}
|
importc: "rl_named_function", dynlib: readlineDll.}
|
||||||
proc function_of_keyseq*(a2: cstring, a3: PKeymap, a4: ptr cint): TCommandFunc{.
|
proc function_of_keyseq*(a2: cstring, a3: PKeymap, a4: ptr cint): CommandFunc{.
|
||||||
cdecl, importc: "rl_function_of_keyseq", dynlib: readlineDll.}
|
cdecl, importc: "rl_function_of_keyseq", dynlib: readlineDll.}
|
||||||
proc list_funmap_names*(){.cdecl, importc: "rl_list_funmap_names",
|
proc list_funmap_names*(){.cdecl, importc: "rl_list_funmap_names",
|
||||||
dynlib: readlineDll.}
|
dynlib: readlineDll.}
|
||||||
proc invoking_keyseqs_in_map*(a2: TCommandFunc, a3: PKeymap): cstringArray{.
|
proc invoking_keyseqs_in_map*(a2: CommandFunc, a3: PKeymap): cstringArray{.
|
||||||
cdecl, importc: "rl_invoking_keyseqs_in_map", dynlib: readlineDll.}
|
cdecl, importc: "rl_invoking_keyseqs_in_map", dynlib: readlineDll.}
|
||||||
proc invoking_keyseqs*(a2: TCommandFunc): cstringArray{.cdecl,
|
proc invoking_keyseqs*(a2: CommandFunc): cstringArray{.cdecl,
|
||||||
importc: "rl_invoking_keyseqs", dynlib: readlineDll.}
|
importc: "rl_invoking_keyseqs", dynlib: readlineDll.}
|
||||||
proc function_dumper*(a2: cint){.cdecl, importc: "rl_function_dumper",
|
proc function_dumper*(a2: cint){.cdecl, importc: "rl_function_dumper",
|
||||||
dynlib: readlineDll.}
|
dynlib: readlineDll.}
|
||||||
|
|
@ -688,7 +688,7 @@ proc get_keymap_name_from_edit_mode*(): cstring{.cdecl,
|
||||||
importc: "rl_get_keymap_name_from_edit_mode", dynlib: readlineDll.}
|
importc: "rl_get_keymap_name_from_edit_mode", dynlib: readlineDll.}
|
||||||
# Functions for manipulating the funmap, which maps command names to functions.
|
# Functions for manipulating the funmap, which maps command names to functions.
|
||||||
|
|
||||||
proc add_funmap_entry*(a2: cstring, a3: TCommandFunc): cint{.cdecl,
|
proc add_funmap_entry*(a2: cstring, a3: CommandFunc): cint{.cdecl,
|
||||||
importc: "rl_add_funmap_entry", dynlib: readlineDll.}
|
importc: "rl_add_funmap_entry", dynlib: readlineDll.}
|
||||||
proc funmap_names*(): cstringArray{.cdecl, importc: "rl_funmap_names",
|
proc funmap_names*(): cstringArray{.cdecl, importc: "rl_funmap_names",
|
||||||
dynlib: readlineDll.}
|
dynlib: readlineDll.}
|
||||||
|
|
@ -828,7 +828,7 @@ proc username_completion_function*(a2: cstring, a3: cint): cstring{.cdecl,
|
||||||
importc: "rl_username_completion_function", dynlib: readlineDll.}
|
importc: "rl_username_completion_function", dynlib: readlineDll.}
|
||||||
proc filename_completion_function*(a2: cstring, a3: cint): cstring{.cdecl,
|
proc filename_completion_function*(a2: cstring, a3: cint): cstring{.cdecl,
|
||||||
importc: "rl_filename_completion_function", dynlib: readlineDll.}
|
importc: "rl_filename_completion_function", dynlib: readlineDll.}
|
||||||
proc completion_mode*(a2: TCommandFunc): cint{.cdecl,
|
proc completion_mode*(a2: CommandFunc): cint{.cdecl,
|
||||||
importc: "rl_completion_mode", dynlib: readlineDll.}
|
importc: "rl_completion_mode", dynlib: readlineDll.}
|
||||||
# ****************************************************************
|
# ****************************************************************
|
||||||
#
|
#
|
||||||
|
|
@ -883,7 +883,7 @@ when false:
|
||||||
# The current value of the numeric argument specified by the user.
|
# The current value of the numeric argument specified by the user.
|
||||||
var numeric_arg*{.importc: "rl_numeric_arg", dynlib: readlineDll.}: cint
|
var numeric_arg*{.importc: "rl_numeric_arg", dynlib: readlineDll.}: cint
|
||||||
# The address of the last command function Readline executed.
|
# The address of the last command function Readline executed.
|
||||||
var last_func*{.importc: "rl_last_func", dynlib: readlineDll.}: TCommandFunc
|
var last_func*{.importc: "rl_last_func", dynlib: readlineDll.}: CommandFunc
|
||||||
# The name of the terminal to use.
|
# The name of the terminal to use.
|
||||||
var terminal_name*{.importc: "rl_terminal_name", dynlib: readlineDll.}: cstring
|
var terminal_name*{.importc: "rl_terminal_name", dynlib: readlineDll.}: cstring
|
||||||
# The input and output streams.
|
# The input and output streams.
|
||||||
|
|
@ -1186,7 +1186,7 @@ type
|
||||||
rlstate*: cint
|
rlstate*: cint
|
||||||
done*: cint
|
done*: cint
|
||||||
kmap*: PKeymap # input state
|
kmap*: PKeymap # input state
|
||||||
lastfunc*: TCommandFunc
|
lastfunc*: CommandFunc
|
||||||
insmode*: cint
|
insmode*: cint
|
||||||
edmode*: cint
|
edmode*: cint
|
||||||
kseqlen*: cint
|
kseqlen*: cint
|
||||||
|
|
|
||||||
|
|
@ -775,7 +775,7 @@ type
|
||||||
Arg*{.final.} = object
|
Arg*{.final.} = object
|
||||||
buf*: array[0..ERR_MAX_STRLEN - 1, int8]
|
buf*: array[0..ERR_MAX_STRLEN - 1, int8]
|
||||||
|
|
||||||
Perror* = ptr Terror
|
Perror* = ptr Error
|
||||||
Error*{.final.} = object # This is a numeric value corresponding to the current error
|
Error*{.final.} = object # This is a numeric value corresponding to the current error
|
||||||
# SDL_rwops.h types
|
# SDL_rwops.h types
|
||||||
# This is the read/write operation structure -- very basic
|
# This is the read/write operation structure -- very basic
|
||||||
|
|
@ -814,7 +814,7 @@ type
|
||||||
theType*: cint
|
theType*: cint
|
||||||
mem*: Mem
|
mem*: Mem
|
||||||
|
|
||||||
RWops* = RWops # SDL_timer.h types
|
# SDL_timer.h types
|
||||||
# Function prototype for the timer callback function
|
# Function prototype for the timer callback function
|
||||||
TimerCallback* = proc (interval: int32): int32{.cdecl.}
|
TimerCallback* = proc (interval: int32): int32{.cdecl.}
|
||||||
NewTimerCallback* = proc (interval: int32, param: pointer): int32{.cdecl.}
|
NewTimerCallback* = proc (interval: int32, param: pointer): int32{.cdecl.}
|
||||||
|
|
@ -950,8 +950,8 @@ type
|
||||||
EventAction* = enum # Application visibility event structure
|
EventAction* = enum # Application visibility event structure
|
||||||
ADDEVENT, PEEKEVENT, GETEVENT
|
ADDEVENT, PEEKEVENT, GETEVENT
|
||||||
|
|
||||||
PActiveEvent* = ptr ActiveEvent
|
PActiveEvent* = ptr TActiveEvent
|
||||||
ActiveEvent*{.final.} = object # SDL_ACTIVEEVENT
|
TActiveEvent*{.final.} = object # SDL_ACTIVEEVENT
|
||||||
# Keyboard event structure
|
# Keyboard event structure
|
||||||
kind*: EventKind
|
kind*: EventKind
|
||||||
gain*: byte # Whether given states were gained or lost (1/0)
|
gain*: byte # Whether given states were gained or lost (1/0)
|
||||||
|
|
@ -1032,8 +1032,8 @@ type
|
||||||
w*: cint # New width
|
w*: cint # New width
|
||||||
h*: cint # New height
|
h*: cint # New height
|
||||||
|
|
||||||
PUserEvent* = ptr UserEvent
|
PUserEvent* = ptr TUserEvent
|
||||||
UserEvent*{.final.} = object # SDL_USEREVENT through SDL_NUMEVENTS-1
|
TUserEvent*{.final.} = object # SDL_USEREVENT through SDL_NUMEVENTS-1
|
||||||
kind*: EventKind
|
kind*: EventKind
|
||||||
code*: cint # User defined event code
|
code*: cint # User defined event code
|
||||||
data1*: pointer # User defined data pointer
|
data1*: pointer # User defined data pointer
|
||||||
|
|
@ -1044,7 +1044,7 @@ type
|
||||||
TWrite: Write, TBool: Bool, TUInt8Array: UInt8Array,
|
TWrite: Write, TBool: Bool, TUInt8Array: UInt8Array,
|
||||||
TGrabMode: GrabMode, Terrorcode: Errorcode, TStdio: Stdio,
|
TGrabMode: GrabMode, Terrorcode: Errorcode, TStdio: Stdio,
|
||||||
TMem: Mem, TSeek: Seek, TRead: Read, TClose: Close,
|
TMem: Mem, TSeek: Seek, TRead: Read, TClose: Close,
|
||||||
TTimerCallback: TimerCallback, TNewTimerCallback: NewTimerCallabck,
|
TTimerCallback: TimerCallback, TNewTimerCallback: NewTimerCallback,
|
||||||
TTimerID: TimerID, TAudioSpecCallback: AudioSpecCallback,
|
TTimerID: TimerID, TAudioSpecCallback: AudioSpecCallback,
|
||||||
TAudioSpec: AudioSpec, TAudioCVTFilter: AudioCVTFilter,
|
TAudioSpec: AudioSpec, TAudioCVTFilter: AudioCVTFilter,
|
||||||
TAudioCVTFilterArray: AudioCVTFilterArray, TAudioCVT: AudioCVT,
|
TAudioCVTFilterArray: AudioCVTFilterArray, TAudioCVT: AudioCVT,
|
||||||
|
|
@ -1053,9 +1053,12 @@ type
|
||||||
TJoystick: Joystick, TJoyAxisEvent: JoyAxisEvent, TRWops: RWops,
|
TJoystick: Joystick, TJoyAxisEvent: JoyAxisEvent, TRWops: RWops,
|
||||||
TJoyBallEvent: JoyBallEvent, TJoyHatEvent: JoyHatEvent,
|
TJoyBallEvent: JoyBallEvent, TJoyHatEvent: JoyHatEvent,
|
||||||
TJoyButtonEvent: JoyButtonEvent, TBallDelta: BallDelta,
|
TJoyButtonEvent: JoyButtonEvent, TBallDelta: BallDelta,
|
||||||
Tversion: Version, TMod: Mod, TActiveEvent: ActiveEvent,
|
Tversion: Version, TMod: Mod,
|
||||||
|
# TActiveEvent: ActiveEvent, # Naming conflict when we drop the `T`
|
||||||
TMouseMotionEvent: MouseMotionEvent, TMouseButtonEvent: MouseButtonEvent,
|
TMouseMotionEvent: MouseMotionEvent, TMouseButtonEvent: MouseButtonEvent,
|
||||||
TResizeEvent: ResizeEvent, TUserEvent: UserEvent].}
|
TResizeEvent: ResizeEvent,
|
||||||
|
# TUserEvent: UserEvent # Naming conflict when we drop the `T`
|
||||||
|
].}
|
||||||
|
|
||||||
when defined(Unix):
|
when defined(Unix):
|
||||||
type #These are the various supported subsystems under UNIX
|
type #These are the various supported subsystems under UNIX
|
||||||
|
|
@ -1136,8 +1139,8 @@ else:
|
||||||
{.deprecated: [TSysWMinfo: SysWMinfo].}
|
{.deprecated: [TSysWMinfo: SysWMinfo].}
|
||||||
|
|
||||||
type
|
type
|
||||||
PSysWMEvent* = ptr SysWMEvent
|
PSysWMEvent* = ptr TSysWMEvent
|
||||||
SysWMEvent*{.final.} = object
|
TSysWMEvent*{.final.} = object
|
||||||
kind*: EventKind
|
kind*: EventKind
|
||||||
msg*: PSysWMmsg
|
msg*: PSysWMmsg
|
||||||
|
|
||||||
|
|
@ -1172,12 +1175,12 @@ type
|
||||||
|
|
||||||
PColorArray* = ptr ColorArray
|
PColorArray* = ptr ColorArray
|
||||||
ColorArray* = array[0..65000, Color]
|
ColorArray* = array[0..65000, Color]
|
||||||
PPalette* = ptr TPalette
|
PPalette* = ptr Palette
|
||||||
Palette*{.final.} = object # Everything in the pixel format structure is read-only
|
Palette*{.final.} = object # Everything in the pixel format structure is read-only
|
||||||
ncolors*: int
|
ncolors*: int
|
||||||
colors*: PColorArray
|
colors*: PColorArray
|
||||||
|
|
||||||
PPixelFormat* = ptr TPixelFormat
|
PPixelFormat* = ptr PixelFormat
|
||||||
PixelFormat*{.final.} = object # The structure passed to the low level blit functions
|
PixelFormat*{.final.} = object # The structure passed to the low level blit functions
|
||||||
palette*: PPalette
|
palette*: PPalette
|
||||||
bitsPerPixel*: byte
|
bitsPerPixel*: byte
|
||||||
|
|
@ -1269,7 +1272,8 @@ type
|
||||||
wmCursor*: pointer # Window-manager cursor
|
wmCursor*: pointer # Window-manager cursor
|
||||||
{.deprecated: [TRect: Rect, TSurface: Surface, TEvent: Event, TColor: Color,
|
{.deprecated: [TRect: Rect, TSurface: Surface, TEvent: Event, TColor: Color,
|
||||||
TEventFilter: EventFilter, TColorArray: ColorArray,
|
TEventFilter: EventFilter, TColorArray: ColorArray,
|
||||||
TSysWMEvent: SysWMEvent, TExposeEvent: ExposeEvent,
|
# TSysWMEvent: SysWMEvent, # Naming conflict when we drop the `T`
|
||||||
|
TExposeEvent: ExposeEvent,
|
||||||
TQuitEvent: QuitEvent, TPalette: Palette, TPixelFormat: PixelFormat,
|
TQuitEvent: QuitEvent, TPalette: Palette, TPixelFormat: PixelFormat,
|
||||||
TBlitInfo: BlitInfo, TBlit: Blit, TVideoInfo: VideoInfo,
|
TBlitInfo: BlitInfo, TBlit: Blit, TVideoInfo: VideoInfo,
|
||||||
TOverlay: Overlay, TGLAttr: GLAttr, TCursor: Cursor].}
|
TOverlay: Overlay, TGLAttr: GLAttr, TCursor: Cursor].}
|
||||||
|
|
@ -1300,7 +1304,7 @@ type # This is the system-independent thread info struc
|
||||||
threadid*: int32
|
threadid*: int32
|
||||||
handle*: SYS_ThreadHandle
|
handle*: SYS_ThreadHandle
|
||||||
status*: int
|
status*: int
|
||||||
errbuf*: Terror
|
errbuf*: Error
|
||||||
data*: pointer
|
data*: pointer
|
||||||
|
|
||||||
PKeyStateArr* = ptr KeyStateArr
|
PKeyStateArr* = ptr KeyStateArr
|
||||||
|
|
@ -2211,7 +2215,7 @@ proc glLoadLibrary*(filename: cstring): int{.cdecl,
|
||||||
proc glGetProcAddress*(procname: cstring): pointer{.cdecl,
|
proc glGetProcAddress*(procname: cstring): pointer{.cdecl,
|
||||||
importc: "SDL_GL_GetProcAddress", dynlib: LibName.}
|
importc: "SDL_GL_GetProcAddress", dynlib: LibName.}
|
||||||
# Set an attribute of the OpenGL subsystem before intialization.
|
# Set an attribute of the OpenGL subsystem before intialization.
|
||||||
proc glSetAttribute*(attr: TGLAttr, value: int): int{.cdecl,
|
proc glSetAttribute*(attr: GLAttr, value: int): int{.cdecl,
|
||||||
importc: "SDL_GL_SetAttribute", dynlib: LibName.}
|
importc: "SDL_GL_SetAttribute", dynlib: LibName.}
|
||||||
# Get an attribute of the OpenGL subsystem from the windowing
|
# Get an attribute of the OpenGL subsystem from the windowing
|
||||||
# interface, such as glX. This is of course different from getting
|
# interface, such as glX. This is of course different from getting
|
||||||
|
|
@ -2220,7 +2224,7 @@ proc glSetAttribute*(attr: TGLAttr, value: int): int{.cdecl,
|
||||||
#
|
#
|
||||||
# Developers should track the values they pass into SDL_GL_SetAttribute
|
# Developers should track the values they pass into SDL_GL_SetAttribute
|
||||||
# themselves if they want to retrieve these values.
|
# themselves if they want to retrieve these values.
|
||||||
proc glGetAttribute*(attr: TGLAttr, value: var int): int{.cdecl,
|
proc glGetAttribute*(attr: GLAttr, value: var int): int{.cdecl,
|
||||||
importc: "SDL_GL_GetAttribute", dynlib: LibName.}
|
importc: "SDL_GL_GetAttribute", dynlib: LibName.}
|
||||||
# Swap the OpenGL buffers, if double-buffering is supported.
|
# Swap the OpenGL buffers, if double-buffering is supported.
|
||||||
proc glSwapBuffers*(){.cdecl, importc: "SDL_GL_SwapBuffers", dynlib: LibName.}
|
proc glSwapBuffers*(){.cdecl, importc: "SDL_GL_SwapBuffers", dynlib: LibName.}
|
||||||
|
|
@ -2267,7 +2271,7 @@ proc wmToggleFullScreen*(surface: PSurface): int{.cdecl,
|
||||||
# Grabbing means that the mouse is confined to the application window,
|
# Grabbing means that the mouse is confined to the application window,
|
||||||
# and nearly all keyboard input is passed directly to the application,
|
# and nearly all keyboard input is passed directly to the application,
|
||||||
# and not interpreted by a window manager, if any.
|
# and not interpreted by a window manager, if any.
|
||||||
proc wmGrabInput*(mode: TGrabMode): GrabMode{.cdecl,
|
proc wmGrabInput*(mode: GrabMode): GrabMode{.cdecl,
|
||||||
importc: "SDL_WM_GrabInput", dynlib: LibName.}
|
importc: "SDL_WM_GrabInput", dynlib: LibName.}
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
# mouse-routines
|
# mouse-routines
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
discard """
|
discard """
|
||||||
line: 7
|
line: 7
|
||||||
errormsg: "undeclared identifier: 'items'"
|
errormsg: "attempting to call undeclared routine: 'items'"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type a = enum b,c,d
|
type a = enum b,c,d
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
discard """
|
discard """
|
||||||
disabled: "true"
|
output: '''[OK] >:)'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Unittest uses lambdalifting at compile-time which we disable for the JS
|
|
||||||
# codegen! So this cannot and will not work for quite some time.
|
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
suite "Bacon":
|
suite "Bacon":
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
discard """
|
discard """
|
||||||
file: "tissue710.nim"
|
file: "tissue710.nim"
|
||||||
line: 8
|
line: 8
|
||||||
errorMsg: "undeclared identifier: '||'"
|
errorMsg: "attempting to call undeclared routine: '||'"
|
||||||
"""
|
"""
|
||||||
var sum = 0
|
var sum = 0
|
||||||
for x in 3..1000:
|
for x in 3..1000:
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
discard """
|
discard """
|
||||||
file: "tnoop.nim"
|
file: "tnoop.nim"
|
||||||
line: 11
|
line: 11
|
||||||
errormsg: "undeclared identifier: 'a'"
|
errormsg: "attempting to call undeclared routine: 'a'"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
discard """
|
discard """
|
||||||
file: "topaque.nim"
|
file: "topaque.nim"
|
||||||
line: 16
|
line: 16
|
||||||
errormsg: "undeclared identifier: \'buffer\'"
|
errormsg: "undeclared field: \'buffer\'"
|
||||||
"""
|
"""
|
||||||
# Test the new opaque types
|
# Test the new opaque types
|
||||||
|
|
||||||
|
|
|
||||||
26
tests/parallel/tptr_to_ref.nim
Normal file
26
tests/parallel/tptr_to_ref.nim
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
# bug #2854
|
||||||
|
|
||||||
|
import locks, threadpool, osproc
|
||||||
|
|
||||||
|
const MAX_WORKERS = 10
|
||||||
|
|
||||||
|
type
|
||||||
|
Killer = object
|
||||||
|
lock: Lock
|
||||||
|
bailed {.guard: lock.}: bool
|
||||||
|
processes {.guard: lock.}: array[0..MAX_WORKERS-1, foreign ptr Process]
|
||||||
|
|
||||||
|
template hold(lock: Lock, body: stmt) =
|
||||||
|
lock.acquire
|
||||||
|
defer: lock.release
|
||||||
|
{.locks: [lock].}:
|
||||||
|
body
|
||||||
|
|
||||||
|
proc initKiller*(): Killer =
|
||||||
|
initLock(result.lock)
|
||||||
|
result.lock.hold:
|
||||||
|
result.bailed = false
|
||||||
|
for i, _ in result.processes:
|
||||||
|
result.processes[i] = nil
|
||||||
|
|
||||||
|
var killer = initKiller()
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
discard """
|
discard """
|
||||||
file: "twrongtupleaccess.nim"
|
file: "twrongtupleaccess.nim"
|
||||||
line: 9
|
line: 9
|
||||||
errormsg: "undeclared identifier: \'setBLAH\'"
|
errormsg: "attempting to call undeclared routine: \'setBLAH\'"
|
||||||
"""
|
"""
|
||||||
# Bugfix
|
# Bugfix
|
||||||
|
|
||||||
|
|
|
||||||
14
tests/vm/tconstobj.nim
Normal file
14
tests/vm/tconstobj.nim
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
discard """
|
||||||
|
output: '''(name: hello)'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
# bug #2774
|
||||||
|
|
||||||
|
type Foo = object
|
||||||
|
name: string
|
||||||
|
|
||||||
|
const fooArray = [
|
||||||
|
Foo(name: "hello")
|
||||||
|
]
|
||||||
|
|
||||||
|
echo fooArray[0]
|
||||||
|
|
@ -538,7 +538,7 @@ when haveZipLib:
|
||||||
var n = "$#.zip" % proj
|
var n = "$#.zip" % proj
|
||||||
if c.outdir.len == 0: n = "build" / n
|
if c.outdir.len == 0: n = "build" / n
|
||||||
else: n = c.outdir / n
|
else: n = c.outdir / n
|
||||||
var z: TZipArchive
|
var z: ZipArchive
|
||||||
if open(z, n, fmWrite):
|
if open(z, n, fmWrite):
|
||||||
addFile(z, proj / buildBatFile32, "build" / buildBatFile32)
|
addFile(z, proj / buildBatFile32, "build" / buildBatFile32)
|
||||||
addFile(z, proj / buildBatFile64, "build" / buildBatFile64)
|
addFile(z, proj / buildBatFile64, "build" / buildBatFile64)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue