parent
d1d7d9e3fe
commit
201a08e9a5
10 changed files with 249 additions and 55 deletions
|
|
@ -26,7 +26,7 @@ bootSwitch(usedNoGC, defined(nogc), "--gc:none")
|
||||||
|
|
||||||
import
|
import
|
||||||
os, msgs, options, nversion, condsyms, strutils, extccomp, platform, lists,
|
os, msgs, options, nversion, condsyms, strutils, extccomp, platform, lists,
|
||||||
wordrecg, parseutils, nimblecmd, idents
|
wordrecg, parseutils, nimblecmd, idents, parseopt
|
||||||
|
|
||||||
# but some have deps to imported modules. Yay.
|
# but some have deps to imported modules. Yay.
|
||||||
bootSwitch(usedTinyC, hasTinyCBackend, "-d:tinyc")
|
bootSwitch(usedTinyC, hasTinyCBackend, "-d:tinyc")
|
||||||
|
|
@ -43,7 +43,7 @@ type
|
||||||
TCmdLinePass* = enum
|
TCmdLinePass* = enum
|
||||||
passCmd1, # first pass over the command line
|
passCmd1, # first pass over the command line
|
||||||
passCmd2, # second pass over the command line
|
passCmd2, # second pass over the command line
|
||||||
passPP # preprocessor called ProcessCommand()
|
passPP # preprocessor called processCommand()
|
||||||
|
|
||||||
proc processCommand*(switch: string, pass: TCmdLinePass)
|
proc processCommand*(switch: string, pass: TCmdLinePass)
|
||||||
proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo)
|
proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo)
|
||||||
|
|
@ -573,3 +573,33 @@ proc processCommand(switch: string, pass: TCmdLinePass) =
|
||||||
var cmd, arg: string
|
var cmd, arg: string
|
||||||
splitSwitch(switch, cmd, arg, pass, gCmdLineInfo)
|
splitSwitch(switch, cmd, arg, pass, gCmdLineInfo)
|
||||||
processSwitch(cmd, arg, pass, gCmdLineInfo)
|
processSwitch(cmd, arg, pass, gCmdLineInfo)
|
||||||
|
|
||||||
|
|
||||||
|
var
|
||||||
|
arguments* = ""
|
||||||
|
# the arguments to be passed to the program that
|
||||||
|
# should be run
|
||||||
|
|
||||||
|
proc processSwitch*(pass: TCmdLinePass; p: OptParser) =
|
||||||
|
# hint[X]:off is parsed as (p.key = "hint[X]", p.val = "off")
|
||||||
|
# we fix this here
|
||||||
|
var bracketLe = strutils.find(p.key, '[')
|
||||||
|
if bracketLe >= 0:
|
||||||
|
var key = substr(p.key, 0, bracketLe - 1)
|
||||||
|
var val = substr(p.key, bracketLe + 1) & ':' & p.val
|
||||||
|
processSwitch(key, val, pass, gCmdLineInfo)
|
||||||
|
else:
|
||||||
|
processSwitch(p.key, p.val, pass, gCmdLineInfo)
|
||||||
|
|
||||||
|
proc processArgument*(pass: TCmdLinePass; p: OptParser;
|
||||||
|
argsCount: var int): bool =
|
||||||
|
if argsCount == 0:
|
||||||
|
options.command = p.key
|
||||||
|
else:
|
||||||
|
if pass == passCmd1: options.commandArgs.add p.key
|
||||||
|
if argsCount == 1:
|
||||||
|
# support UNIX style filenames anywhere for portable build scripts:
|
||||||
|
options.gProjectName = unixToNativePath(p.key)
|
||||||
|
arguments = cmdLineRest(p)
|
||||||
|
result = true
|
||||||
|
inc argsCount
|
||||||
|
|
|
||||||
|
|
@ -164,12 +164,6 @@ proc commandEval(exp: string) =
|
||||||
var echoExp = "echo \"eval\\t\", " & "repr(" & exp & ")"
|
var echoExp = "echo \"eval\\t\", " & "repr(" & exp & ")"
|
||||||
evalNim(echoExp.parseString, makeStdinModule())
|
evalNim(echoExp.parseString, makeStdinModule())
|
||||||
|
|
||||||
proc commandPrettyOld =
|
|
||||||
var projectFile = addFileExt(mainCommandArg(), NimExt)
|
|
||||||
var module = parseFile(projectFile.fileInfoIdx)
|
|
||||||
if module != nil:
|
|
||||||
renderModule(module, getOutFile(mainCommandArg(), "pretty." & NimExt))
|
|
||||||
|
|
||||||
proc commandPretty =
|
proc commandPretty =
|
||||||
msgs.gErrorMax = high(int) # do not stop after first error
|
msgs.gErrorMax = high(int) # do not stop after first error
|
||||||
semanticPasses()
|
semanticPasses()
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ proc handleCmdLine() =
|
||||||
if msgs.gErrorCounter == 0:
|
if msgs.gErrorCounter == 0:
|
||||||
when hasTinyCBackend:
|
when hasTinyCBackend:
|
||||||
if gCmd == cmdRun:
|
if gCmd == cmdRun:
|
||||||
tccgen.run(service.arguments)
|
tccgen.run(commands.arguments)
|
||||||
if optRun in gGlobalOptions:
|
if optRun in gGlobalOptions:
|
||||||
if gCmd == cmdCompileToJS:
|
if gCmd == cmdCompileToJS:
|
||||||
var ex: string
|
var ex: string
|
||||||
|
|
@ -67,7 +67,7 @@ proc handleCmdLine() =
|
||||||
else:
|
else:
|
||||||
ex = quoteShell(
|
ex = quoteShell(
|
||||||
completeCFilePath(changeFileExt(gProjectFull, "js").prependCurDir))
|
completeCFilePath(changeFileExt(gProjectFull, "js").prependCurDir))
|
||||||
execExternalProgram("node " & ex & ' ' & service.arguments)
|
execExternalProgram("node " & ex & ' ' & commands.arguments)
|
||||||
else:
|
else:
|
||||||
var binPath: string
|
var binPath: string
|
||||||
if options.outFile.len > 0:
|
if options.outFile.len > 0:
|
||||||
|
|
@ -77,7 +77,7 @@ proc handleCmdLine() =
|
||||||
# Figure out ourselves a valid binary name.
|
# Figure out ourselves a valid binary name.
|
||||||
binPath = changeFileExt(gProjectFull, ExeExt).prependCurDir
|
binPath = changeFileExt(gProjectFull, ExeExt).prependCurDir
|
||||||
var ex = quoteShell(binPath)
|
var ex = quoteShell(binPath)
|
||||||
execExternalProgram(ex & ' ' & service.arguments)
|
execExternalProgram(ex & ' ' & commands.arguments)
|
||||||
|
|
||||||
when declared(GC_setMaxPause):
|
when declared(GC_setMaxPause):
|
||||||
GC_setMaxPause 2_000
|
GC_setMaxPause 2_000
|
||||||
|
|
|
||||||
|
|
@ -14,14 +14,20 @@ import
|
||||||
strutils, os, options, ast, astalgo, msgs, ropes, idents, passes,
|
strutils, os, options, ast, astalgo, msgs, ropes, idents, passes,
|
||||||
intsets, strtabs, semdata, prettybase
|
intsets, strtabs, semdata, prettybase
|
||||||
|
|
||||||
|
|
||||||
|
type
|
||||||
|
StyleCheck* {.pure.} = enum None, Confirm, Auto
|
||||||
|
|
||||||
|
var
|
||||||
|
gOverWrite* = true
|
||||||
|
gStyleCheck*: StyleCheck
|
||||||
|
gCheckExtern*: bool
|
||||||
|
|
||||||
type
|
type
|
||||||
TGen = object of TPassContext
|
TGen = object of TPassContext
|
||||||
module*: PSym
|
module*: PSym
|
||||||
PGen = ref TGen
|
PGen = ref TGen
|
||||||
|
|
||||||
var
|
|
||||||
gCheckExtern: bool
|
|
||||||
|
|
||||||
proc overwriteFiles*() =
|
proc overwriteFiles*() =
|
||||||
let overWrite = options.getConfigVar("pretty.overwrite").normalize != "off"
|
let overWrite = options.getConfigVar("pretty.overwrite").normalize != "off"
|
||||||
let doStrip = options.getConfigVar("pretty.strip").normalize == "on"
|
let doStrip = options.getConfigVar("pretty.strip").normalize == "on"
|
||||||
|
|
|
||||||
|
|
@ -25,39 +25,17 @@ var
|
||||||
lastCaasCmd* = ""
|
lastCaasCmd* = ""
|
||||||
# in caas mode, the list of defines and options will be given at start-up?
|
# in caas mode, the list of defines and options will be given at start-up?
|
||||||
# it's enough to check that the previous compilation command is the same?
|
# it's enough to check that the previous compilation command is the same?
|
||||||
arguments* = ""
|
|
||||||
# the arguments to be passed to the program that
|
|
||||||
# should be run
|
|
||||||
|
|
||||||
proc processCmdLine*(pass: TCmdLinePass, cmd: string) =
|
proc processCmdLine*(pass: TCmdLinePass, cmd: string) =
|
||||||
var p = parseopt.initOptParser(cmd)
|
var p = parseopt.initOptParser(cmd)
|
||||||
var argsCount = 0
|
var argsCount = 0
|
||||||
while true:
|
while true:
|
||||||
parseopt.next(p)
|
parseopt.next(p)
|
||||||
case p.kind
|
case p.kind
|
||||||
of cmdEnd: break
|
of cmdEnd: break
|
||||||
of cmdLongoption, cmdShortOption:
|
of cmdLongoption, cmdShortOption: processSwitch(pass, p)
|
||||||
# hint[X]:off is parsed as (p.key = "hint[X]", p.val = "off")
|
|
||||||
# we fix this here
|
|
||||||
var bracketLe = strutils.find(p.key, '[')
|
|
||||||
if bracketLe >= 0:
|
|
||||||
var key = substr(p.key, 0, bracketLe - 1)
|
|
||||||
var val = substr(p.key, bracketLe + 1) & ':' & p.val
|
|
||||||
processSwitch(key, val, pass, gCmdLineInfo)
|
|
||||||
else:
|
|
||||||
processSwitch(p.key, p.val, pass, gCmdLineInfo)
|
|
||||||
of cmdArgument:
|
of cmdArgument:
|
||||||
if argsCount == 0:
|
if processArgument(pass, p, argsCount): break
|
||||||
options.command = p.key
|
|
||||||
else:
|
|
||||||
if pass == passCmd1: options.commandArgs.add p.key
|
|
||||||
if argsCount == 1:
|
|
||||||
# support UNIX style filenames anywhere for portable build scripts:
|
|
||||||
options.gProjectName = unixToNativePath(p.key)
|
|
||||||
arguments = cmdLineRest(p)
|
|
||||||
break
|
|
||||||
inc argsCount
|
|
||||||
|
|
||||||
if pass == passCmd2:
|
if pass == passCmd2:
|
||||||
if optRun notin gGlobalOptions and arguments != "" and options.command.normalize != "run":
|
if optRun notin gGlobalOptions and arguments != "" and options.command.normalize != "run":
|
||||||
rawMessage(errArgsNeedRunOption, [])
|
rawMessage(errArgsNeedRunOption, [])
|
||||||
|
|
|
||||||
|
|
@ -43,18 +43,19 @@ type
|
||||||
proc debugInfo(info: TLineInfo): string =
|
proc debugInfo(info: TLineInfo): string =
|
||||||
result = info.toFilename.splitFile.name & ":" & $info.line
|
result = info.toFilename.splitFile.name & ":" & $info.line
|
||||||
|
|
||||||
proc codeListing(c: PCtx, result: var string, start=0) =
|
proc codeListing(c: PCtx, result: var string, start=0; last = -1) =
|
||||||
# first iteration: compute all necessary labels:
|
# first iteration: compute all necessary labels:
|
||||||
var jumpTargets = initIntSet()
|
var jumpTargets = initIntSet()
|
||||||
|
|
||||||
for i in start.. < c.code.len:
|
let last = if last < 0: c.code.len-1 else: min(last, c.code.len-1)
|
||||||
|
for i in start..last:
|
||||||
let x = c.code[i]
|
let x = c.code[i]
|
||||||
if x.opcode in relativeJumps:
|
if x.opcode in relativeJumps:
|
||||||
jumpTargets.incl(i+x.regBx-wordExcess)
|
jumpTargets.incl(i+x.regBx-wordExcess)
|
||||||
|
|
||||||
# for debugging purposes
|
# for debugging purposes
|
||||||
var i = start
|
var i = start
|
||||||
while i < c.code.len:
|
while i <= last:
|
||||||
if i in jumpTargets: result.addf("L$1:\n", i)
|
if i in jumpTargets: result.addf("L$1:\n", i)
|
||||||
let x = c.code[i]
|
let x = c.code[i]
|
||||||
|
|
||||||
|
|
@ -82,9 +83,9 @@ proc codeListing(c: PCtx, result: var string, start=0) =
|
||||||
result.add("\n")
|
result.add("\n")
|
||||||
inc i
|
inc i
|
||||||
|
|
||||||
proc echoCode*(c: PCtx, start=0) {.deprecated.} =
|
proc echoCode*(c: PCtx; start=0; last = -1) {.deprecated.} =
|
||||||
var buf = ""
|
var buf = ""
|
||||||
codeListing(c, buf, start)
|
codeListing(c, buf, start, last)
|
||||||
echo buf
|
echo buf
|
||||||
|
|
||||||
proc gABC(ctx: PCtx; n: PNode; opc: TOpcode; a, b, c: TRegister = 0) =
|
proc gABC(ctx: PCtx; n: PNode; opc: TOpcode; a, b, c: TRegister = 0) =
|
||||||
|
|
@ -495,6 +496,7 @@ proc genCall(c: PCtx; n: PNode; dest: var TDest) =
|
||||||
c.freeTempRange(x, n.len)
|
c.freeTempRange(x, n.len)
|
||||||
|
|
||||||
template isGlobal(s: PSym): bool = sfGlobal in s.flags and s.kind != skForVar
|
template isGlobal(s: PSym): bool = sfGlobal in s.flags and s.kind != skForVar
|
||||||
|
proc isGlobal(n: PNode): bool = n.kind == nkSym and isGlobal(n.sym)
|
||||||
|
|
||||||
proc needsAsgnPatch(n: PNode): bool =
|
proc needsAsgnPatch(n: PNode): bool =
|
||||||
n.kind in {nkBracketExpr, nkDotExpr, nkCheckedFieldExpr,
|
n.kind in {nkBracketExpr, nkDotExpr, nkCheckedFieldExpr,
|
||||||
|
|
@ -637,8 +639,10 @@ proc genBinaryStmt(c: PCtx; n: PNode; opc: TOpcode) =
|
||||||
c.freeTemp(tmp)
|
c.freeTemp(tmp)
|
||||||
|
|
||||||
proc genBinaryStmtVar(c: PCtx; n: PNode; opc: TOpcode) =
|
proc genBinaryStmtVar(c: PCtx; n: PNode; opc: TOpcode) =
|
||||||
|
var x = n.sons[1]
|
||||||
|
if x.kind in {nkAddr, nkHiddenAddr}: x = x.sons[0]
|
||||||
let
|
let
|
||||||
dest = c.genx(n.sons[1], {gfAddrOf})
|
dest = c.genx(x)
|
||||||
tmp = c.genx(n.sons[2])
|
tmp = c.genx(n.sons[2])
|
||||||
c.gABC(n, opc, dest, tmp, 0)
|
c.gABC(n, opc, dest, tmp, 0)
|
||||||
#c.genAsgnPatch(n.sons[1], dest)
|
#c.genAsgnPatch(n.sons[1], dest)
|
||||||
|
|
@ -1053,6 +1057,8 @@ proc genAddrDeref(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode;
|
||||||
# nkAddr we must not use 'unneededIndirection', but for deref we use it.
|
# nkAddr we must not use 'unneededIndirection', but for deref we use it.
|
||||||
if not isAddr and unneededIndirection(n.sons[0]):
|
if not isAddr and unneededIndirection(n.sons[0]):
|
||||||
gen(c, n.sons[0], dest, newflags)
|
gen(c, n.sons[0], dest, newflags)
|
||||||
|
elif isGlobal(n.sons[0]):
|
||||||
|
gen(c, n.sons[0], dest, flags+{gfAddrOf})
|
||||||
else:
|
else:
|
||||||
let tmp = c.genx(n.sons[0], newflags)
|
let tmp = c.genx(n.sons[0], newflags)
|
||||||
if dest < 0: dest = c.getTemp(n.typ)
|
if dest < 0: dest = c.getTemp(n.typ)
|
||||||
|
|
@ -1062,6 +1068,9 @@ proc genAddrDeref(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode;
|
||||||
c.gABC(n, opcNodeToReg, dest, dest)
|
c.gABC(n, opcNodeToReg, dest, dest)
|
||||||
elif c.prc.slots[tmp].kind >= slotTempUnknown:
|
elif c.prc.slots[tmp].kind >= slotTempUnknown:
|
||||||
gABC(c, n, opcAddrNode, dest, tmp)
|
gABC(c, n, opcAddrNode, dest, tmp)
|
||||||
|
# XXX this can still be wrong sometimes; hopefully it's only generated
|
||||||
|
# in call contexts, where it is safe
|
||||||
|
#message(n.info, warnUser, "suspicious opcode used")
|
||||||
else:
|
else:
|
||||||
gABC(c, n, opcAddrReg, dest, tmp)
|
gABC(c, n, opcAddrReg, dest, tmp)
|
||||||
c.freeTemp(tmp)
|
c.freeTemp(tmp)
|
||||||
|
|
@ -1247,6 +1256,8 @@ proc genRdVar(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
|
||||||
c.gABx(n, opcLdGlobal, cc, s.position)
|
c.gABx(n, opcLdGlobal, cc, s.position)
|
||||||
c.gABC(n, opcNodeToReg, dest, cc)
|
c.gABC(n, opcNodeToReg, dest, cc)
|
||||||
c.freeTemp(cc)
|
c.freeTemp(cc)
|
||||||
|
elif gfAddrOf in flags:
|
||||||
|
c.gABx(n, opcLdGlobalAddr, dest, s.position)
|
||||||
else:
|
else:
|
||||||
c.gABx(n, opcLdGlobal, dest, s.position)
|
c.gABx(n, opcLdGlobal, dest, s.position)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -187,7 +187,7 @@ proc processClient(client: PAsyncSocket, address: string,
|
||||||
request.client.close()
|
request.client.close()
|
||||||
break
|
break
|
||||||
|
|
||||||
proc serve*(server: PAsyncHttpServer, port: TPort,
|
proc serve*(server: PAsyncHttpServer, port: Port,
|
||||||
callback: proc (request: TRequest): PFuture[void] {.closure,gcsafe.},
|
callback: proc (request: TRequest): PFuture[void] {.closure,gcsafe.},
|
||||||
address = "") {.async.} =
|
address = "") {.async.} =
|
||||||
## Starts the process of listening for incoming HTTP connections on the
|
## Starts the process of listening for incoming HTTP connections on the
|
||||||
|
|
|
||||||
174
tests/vm/tasmparser.nim
Normal file
174
tests/vm/tasmparser.nim
Normal file
|
|
@ -0,0 +1,174 @@
|
||||||
|
|
||||||
|
# bug #1513
|
||||||
|
|
||||||
|
import os, parseutils, strutils, ropes, macros
|
||||||
|
|
||||||
|
var
|
||||||
|
code {.compileTime.} = ""
|
||||||
|
start {.compileTime.} = 0
|
||||||
|
line {.compileTime.} = 1
|
||||||
|
cpp {.compileTime.} = ""
|
||||||
|
token {.compileTime.} = ""
|
||||||
|
|
||||||
|
proc log (msg: string) {.compileTime.} =
|
||||||
|
echo msg
|
||||||
|
|
||||||
|
proc asmx64 () {.compileTime} =
|
||||||
|
|
||||||
|
#log "code = $1" % code
|
||||||
|
|
||||||
|
const asmx64pre = "{.emit: \"\"\"{x64asm& x= *x64asm_ptr(`asm0`); try {"
|
||||||
|
const asmx64post = "} catch (Xbyak::Error e) { printf (\"asmx64 error: %s\\n\", e.what ()); }}\"\"\".} "
|
||||||
|
|
||||||
|
const xp = "x."
|
||||||
|
|
||||||
|
const symbolStart = { '_', 'a'..'z', 'A' .. 'Z' }
|
||||||
|
const symbol = { '0'..'9' } + symbolStart
|
||||||
|
const eolComment = { ';' }
|
||||||
|
const endOfLine = { '\l', '\r' }
|
||||||
|
const leadingWhiteSpace = { ' ' }
|
||||||
|
|
||||||
|
const end_or_comment = endOfLine + eolComment + { '\0' }
|
||||||
|
|
||||||
|
const passthrough_start = { '{', '`' }
|
||||||
|
const passthrough_end = { '}', '`', '\0' }
|
||||||
|
|
||||||
|
const end_or_symbol_or_comment_or_passthrough = symbolStart + end_or_comment + passthrough_start
|
||||||
|
|
||||||
|
|
||||||
|
proc abortAsmParse (err:string) =
|
||||||
|
#
|
||||||
|
|
||||||
|
let codeLen = code.len
|
||||||
|
#let codeEnd = codeLen-1
|
||||||
|
cpp.add asmx64pre
|
||||||
|
|
||||||
|
#log "{$1}\n" % [code]
|
||||||
|
|
||||||
|
type asmParseState = enum leading, mnemonic, betweenArguments, arguments, endCmd, skipToEndOfLine
|
||||||
|
|
||||||
|
var state:asmParseState = leading
|
||||||
|
|
||||||
|
proc checkEnd (err:string) =
|
||||||
|
let ch = code [start]
|
||||||
|
if int (ch) == 0:
|
||||||
|
abortAsmParse (err)
|
||||||
|
|
||||||
|
proc get_passthrough () =
|
||||||
|
inc start
|
||||||
|
let prev_start = start
|
||||||
|
let prev_token = token
|
||||||
|
start += code.parseUntil (token, passthrough_end, start)
|
||||||
|
checkEnd ("Failed to find passthrough end delimiter from offset $1 for:$2\n$3" % [$prev_start, $(code [prev_start-prev_token.len..prev_start]), token[1..token.len-1]])
|
||||||
|
inc start
|
||||||
|
cpp.add "`"
|
||||||
|
cpp.add token
|
||||||
|
cpp.add "`"
|
||||||
|
|
||||||
|
var inparse = true
|
||||||
|
|
||||||
|
proc checkCmdEnd () =
|
||||||
|
if codeLen == start:
|
||||||
|
state = endCmd
|
||||||
|
inparse = false
|
||||||
|
|
||||||
|
while inparse:
|
||||||
|
checkCmdEnd ()
|
||||||
|
|
||||||
|
log ("state=$1 start=$2" % [$state, $start])
|
||||||
|
|
||||||
|
case state:
|
||||||
|
of leading:
|
||||||
|
|
||||||
|
echo "b100 ", start
|
||||||
|
start += code.skipWhile (leadingWhiteSpace, start)
|
||||||
|
echo "b200 ", start
|
||||||
|
let ch = code [start]
|
||||||
|
if ch in endOfLine:
|
||||||
|
inc (line)
|
||||||
|
#echo "c100 ", start, ' ', code
|
||||||
|
start += code.skipWhile (endOfline, start)
|
||||||
|
#echo "c200 ", start, ' ', code
|
||||||
|
continue
|
||||||
|
elif ch in symbolStart:
|
||||||
|
state = mnemonic
|
||||||
|
elif ch in eolComment:
|
||||||
|
state = skipToEndOfLine
|
||||||
|
elif ch in passthrough_start:
|
||||||
|
get_passthrough ()
|
||||||
|
echo "d100 ", start
|
||||||
|
start += code.parseUntil (token, end_or_symbol_or_comment_or_passthrough, start)
|
||||||
|
echo "d200 ", start
|
||||||
|
cpp.add token
|
||||||
|
state = mnemonic
|
||||||
|
elif int (ch) == 0:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
abortAsmParse ("after '$3' illegal character at offset $1: $2" % [$start, $(int (ch)), token])
|
||||||
|
|
||||||
|
of mnemonic:
|
||||||
|
echo "e100 ", start
|
||||||
|
start += code.parseWhile (token, symbol, start)
|
||||||
|
echo "e200 ", start
|
||||||
|
cpp.add xp
|
||||||
|
cpp.add token
|
||||||
|
cpp.add "("
|
||||||
|
state = betweenArguments
|
||||||
|
|
||||||
|
of betweenArguments:
|
||||||
|
let tmp = start
|
||||||
|
let rcode = code
|
||||||
|
start += rcode.parseUntil (token, end_or_symbol_or_comment_or_passthrough, tmp)
|
||||||
|
cpp.add token
|
||||||
|
|
||||||
|
if codeLen <= start:
|
||||||
|
state = endCmd
|
||||||
|
continue
|
||||||
|
|
||||||
|
let ch = code [start]
|
||||||
|
if ch in passthrough_start:
|
||||||
|
get_passthrough ()
|
||||||
|
continue
|
||||||
|
if (ch in {'x', 'X'}) and ('0' == code [start-1]):
|
||||||
|
token = $(code [start])
|
||||||
|
cpp.add token
|
||||||
|
inc start
|
||||||
|
continue
|
||||||
|
state = arguments
|
||||||
|
|
||||||
|
of arguments:
|
||||||
|
if code [start] in end_or_comment:
|
||||||
|
state = endCmd
|
||||||
|
continue
|
||||||
|
start += code.parseWhile (token, symbol, start)
|
||||||
|
cpp.add xp
|
||||||
|
cpp.add token
|
||||||
|
state = betweenArguments
|
||||||
|
|
||||||
|
of endCmd:
|
||||||
|
cpp.add ");\n"
|
||||||
|
state = skipToEndOfLine
|
||||||
|
|
||||||
|
of skipToEndOfLine:
|
||||||
|
echo "a100 ", start
|
||||||
|
start += code.skipUntil (endOfLine, start)
|
||||||
|
echo "a200 ", start
|
||||||
|
start += code.skipWhile (endOfline, start)
|
||||||
|
echo "a300 ", start
|
||||||
|
inc line
|
||||||
|
state = leading
|
||||||
|
|
||||||
|
cpp.add asmx64post
|
||||||
|
|
||||||
|
echo ($cpp)
|
||||||
|
|
||||||
|
macro asmx64x (code_in:expr) : stmt =
|
||||||
|
code = $code_in
|
||||||
|
echo ("code.len = $1, code = >>>$2<<<" % [$code.len, code])
|
||||||
|
asmx64 ()
|
||||||
|
discard result
|
||||||
|
|
||||||
|
asmx64x """
|
||||||
|
mov rax, {m}
|
||||||
|
ret
|
||||||
|
"""
|
||||||
|
|
@ -2,18 +2,19 @@ discard """
|
||||||
msg: '''2
|
msg: '''2
|
||||||
3
|
3
|
||||||
4:2
|
4:2
|
||||||
'''
|
Got Hi
|
||||||
|
Got Hey'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# bug #404
|
# bug #404
|
||||||
|
|
||||||
import macros, tables
|
import macros, tables, strtabs
|
||||||
|
|
||||||
var ZOOT{.compileTime.} = initTable[int, int](2)
|
var ZOOT{.compileTime.} = initTable[int, int](2)
|
||||||
var iii {.compiletime.} = 1
|
var iii {.compiletime.} = 1
|
||||||
|
|
||||||
macro zoo:stmt=
|
macro zoo:stmt=
|
||||||
zoot[iii] = iii*2
|
ZOOT[iii] = iii*2
|
||||||
inc iii
|
inc iii
|
||||||
echo iii
|
echo iii
|
||||||
|
|
||||||
|
|
@ -29,9 +30,7 @@ tupleUnpack
|
||||||
|
|
||||||
# bug #903
|
# bug #903
|
||||||
|
|
||||||
import strtabs
|
var x {.compileTime.}: StringTableRef
|
||||||
|
|
||||||
var x {.compileTime.}: PStringTable
|
|
||||||
|
|
||||||
macro addStuff(stuff, body: expr): stmt {.immediate.} =
|
macro addStuff(stuff, body: expr): stmt {.immediate.} =
|
||||||
result = newNimNode(nnkStmtList)
|
result = newNimNode(nnkStmtList)
|
||||||
|
|
|
||||||
4
todo.txt
4
todo.txt
|
|
@ -1,7 +1,9 @@
|
||||||
version 0.10
|
version 0.10
|
||||||
============
|
============
|
||||||
|
|
||||||
- Test nim pretty on various babel packages
|
- Write new nimfix tool
|
||||||
|
- Test nimfix on various babel packages
|
||||||
|
- Pegs do not work at compile-time
|
||||||
|
|
||||||
|
|
||||||
version 0.9.6
|
version 0.9.6
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue