revert new scope for 'if'

This commit is contained in:
Araq 2013-05-02 00:36:06 +02:00
commit 1dd01e5891
8 changed files with 182 additions and 6 deletions

View file

@ -232,13 +232,14 @@ proc genIfStmt(p: BProc, n: PNode) =
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
var it = n.sons[i] var it = n.sons[i]
if it.len == 2: if it.len == 2:
startBlock(p) when newScopeForIf: startBlock(p)
initLocExpr(p, it.sons[0], a) initLocExpr(p, it.sons[0], a)
Lelse = getLabel(p) Lelse = getLabel(p)
inc(p.labels) inc(p.labels)
lineFF(p, cpsStmts, "if (!$1) goto $2;$n", lineFF(p, cpsStmts, "if (!$1) goto $2;$n",
"br i1 $1, label %LOC$3, label %$2$n" & "LOC$3: $n", "br i1 $1, label %LOC$3, label %$2$n" & "LOC$3: $n",
[rdLoc(a), Lelse, toRope(p.labels)]) [rdLoc(a), Lelse, toRope(p.labels)])
when not newScopeForIf: startBlock(p)
genStmts(p, it.sons[1]) genStmts(p, it.sons[1])
endBlock(p) endBlock(p)
if sonsLen(n) > 1: if sonsLen(n) > 1:

View file

@ -7,13 +7,14 @@
# distribution, for details about the copyright. # distribution, for details about the copyright.
# #
import import
os, lists, strutils, strtabs os, lists, strutils, strtabs
const const
hasTinyCBackend* = defined(tinyc) hasTinyCBackend* = defined(tinyc)
useEffectSystem* = true useEffectSystem* = true
hasFFI* = defined(useFFI) hasFFI* = defined(useFFI)
newScopeForIf* = false # XXX activate for 0.9.4
type # please make sure we have under 32 options type # please make sure we have under 32 options
# (improves code efficiency a lot!) # (improves code efficiency a lot!)

View file

@ -100,7 +100,7 @@ proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym =
proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym = proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym =
# like newSymS, but considers gensym'ed symbols # like newSymS, but considers gensym'ed symbols
if n.kind == nkSym: if n.kind == nkSym:
result = n.sym result = n.sym
InternalAssert sfGenSym in result.flags InternalAssert sfGenSym in result.flags
InternalAssert result.kind == kind InternalAssert result.kind == kind

View file

@ -1504,8 +1504,9 @@ proc semIf(c: PContext, n: PNode): PNode =
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
var it = n.sons[i] var it = n.sons[i]
if it.len == 2: if it.len == 2:
openScope(c.tab) when newScopeForIf: openScope(c.tab)
it.sons[0] = forceBool(c, semExprWithType(c, it.sons[0])) it.sons[0] = forceBool(c, semExprWithType(c, it.sons[0]))
when not newScopeForIf: openScope(c.tab)
it.sons[1] = semExprBranch(c, it.sons[1]) it.sons[1] = semExprBranch(c, it.sons[1])
typ = commonType(typ, it.sons[1].typ) typ = commonType(typ, it.sons[1].typ)
closeScope(c.tab) closeScope(c.tab)

View file

@ -1918,7 +1918,9 @@ the corresponding *then* block:
else: else:
# 'm' not declared here # 'm' not declared here
In the example the scopes have been enclosed in ``{| |}``. In the example the scopes have been enclosed in ``{| |}``.
**Note**: These scoping rules will be active in 0.9.4.
Case statement Case statement

View file

@ -0,0 +1,87 @@
import argument_parser, tables, strutils, parseutils
## Example defining a subset of wget's functionality
const
PARAM_VERSION = @["-V", "--version"]
PARAM_HELP = @["-h", "--help"]
PARAM_BACKGROUND = @["-b", "--background"]
PARAM_OUTPUT = @["-o", "--output"]
PARAM_NO_CLOBBER = @["-nc", "--no-clobber"]
PARAM_PROGRESS = "--progress"
PARAM_NO_PROXY = "--no-proxy"
template P(tnames: varargs[string], thelp: string, ttype = PK_EMPTY,
tcallback: Tparameter_callback = nil) =
## Helper to avoid repetition of parameter adding boilerplate.
params.add(new_parameter_specification(ttype, custom_validator = tcallback,
help_text = thelp, names = tnames))
template got(param: varargs[string]) =
## Just dump the detected options on output.
if result.options.hasKey(param[0]): echo("Found option '$1'." % [param[0]])
proc parse_progress(parameter: string; value: var Tparsed_parameter): string =
## Custom parser and validator of progress types for PARAM_PROGRESS.
##
## If the user specifies the PARAM_PROGRESS option this proc will be called
## so we can validate the input. The proc returns a non empty string if
## something went wrong with the description of the error, otherwise
## execution goes ahead.
##
## This validator only accepts values without changing the final output.
if value.str_val == "bar" or value.str_val == "dot":
return
result = "The string $1 is not valid, use bar or dot." % [value.str_val]
proc process_commandline(): Tcommandline_results =
## Parses the commandline.
##
## Returns a Tcommandline_results with at least two positional parameter,
## where the last parameter is implied to be the destination of the copying.
var params: seq[Tparameter_specification] = @[]
P(PARAM_VERSION, "Shows the version of the program")
P(PARAM_HELP, "Shows this help on the commandline", PK_HELP)
P(PARAM_BACKGROUND, "Continues execution in the background")
P(PARAM_OUTPUT, "Specifies a specific output file name", PK_STRING)
P(PARAM_NO_CLOBBER, "Skip downloads that would overwrite existing files")
P(PARAM_PROGRESS, "Select progress look (bar or dot)",
PK_STRING, parse_progress)
P(PARAM_NO_PROXY, "Don't use proxies even if available")
result = parse(params)
if result.positional_parameters.len < 1:
echo "Missing URL(s) to download"
echo_help(params)
quit()
got(PARAM_NO_CLOBBER)
got(PARAM_BACKGROUND)
got(PARAM_NO_PROXY)
if result.options.hasKey(PARAM_VERSION[0]):
echo "Version 3.1415"
quit()
if result.options.hasKey(PARAM_OUTPUT[0]):
if result.positional_parameters.len > 1:
echo "Error: can't use $1 option with multiple URLs" % [PARAM_OUTPUT[0]]
echo_help(params)
quit()
echo "Will download to $1" % [result.options[PARAM_OUTPUT[0]].str_val]
if result.options.hasKey(PARAM_PROGRESS):
echo "Will use progress type $1" % [result.options[PARAM_PROGRESS].str_val]
when isMainModule:
let args = process_commandline()
for param in args.positional_parameters:
echo "Downloading $1" % param.str_val

View file

@ -0,0 +1,83 @@
discard """
DO AS THOU WILST PUBLIC LICENSE
Whoever should stumble upon this document is henceforth and forever
entitled to DO AS THOU WILST with aforementioned document and the
contents thereof.
As said in the Olde Country, `Keepe it Gangster'."""
import strutils, parseopt, tables, os
type
PTask* = ref object
desc*: string
action*: TTaskFunction
TTaskFunction* = proc() {.closure.}
var
tasks* = initTable[string, PTask](16)
proc newTask*(desc: string; action: TTaskFunction): PTask
proc runTask*(name: string) {.inline.}
proc shell*(cmd: varargs[string, `$`]): int {.discardable.}
proc cd*(dir: string) {.inline.}
template nakeImports*(): stmt {.immediate.} =
import tables, parseopt, strutils, os
template task*(name: string; description: string; body: stmt): stmt {.dirty, immediate.} =
block:
var t = newTask(description, proc() {.closure.} =
body)
tasks[name] = t
proc newTask*(desc: string; action: TTaskFunction): PTask =
new(result)
result.desc = desc
result.action = action
proc runTask*(name: string) = tasks[name].action()
proc shell*(cmd: varargs[string, `$`]): int =
result = execShellCmd(cmd.join(" "))
proc cd*(dir: string) = setCurrentDir(dir)
template withDir*(dir: string; body: stmt): stmt =
## temporary cd
## withDir "foo":
## # inside foo
## #back to last dir
var curDir = getCurrentDir()
cd(dir)
body
cd(curDir)
when isMainModule:
if not existsFile("nakefile.nim"):
echo "No nakefile.nim found. Current working dir is ", getCurrentDir()
quit 1
var args = ""
for i in 1..paramCount():
args.add paramStr(i)
args.add " "
quit(shell("nimrod", "c", "-r", "nakefile.nim", args))
else:
addQuitProc(proc() {.noconv.} =
var
task: string
printTaskList: bool
for kind, key, val in getOpt():
case kind
of cmdLongOption, cmdShortOption:
case key.tolower
of "tasks", "t":
printTaskList = true
else:
echo "Unknown option: ", key, ": ", val
of cmdArgument:
task = key
else: nil
if printTaskList or task.isNil or not(tasks.hasKey(task)):
echo "Available tasks:"
for name, task in pairs(tasks):
echo name, " - ", task.desc
quit 0
tasks[task].action())

View file

@ -216,7 +216,8 @@ proc compileManyLoc(r: var TResults, options: string) =
for kind, dir in os.walkDir("tests/manyloc"): for kind, dir in os.walkDir("tests/manyloc"):
if kind == pcDir: if kind == pcDir:
let mainfile = findMainFile(dir) let mainfile = findMainFile(dir)
compileSingleTest(r, mainfile, options) if mainfile != ".nim":
compileSingleTest(r, mainfile, options)
proc compileSpecialTests(r: var TResults, options: string) = proc compileSpecialTests(r: var TResults, options: string) =
compileRodFiles(r, options) compileRodFiles(r, options)