revert new scope for 'if'

This commit is contained in:
Araq
2013-05-02 00:36:06 +02:00
parent c75aa98706
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):
var it = n.sons[i]
if it.len == 2:
startBlock(p)
when newScopeForIf: startBlock(p)
initLocExpr(p, it.sons[0], a)
Lelse = getLabel(p)
inc(p.labels)
lineFF(p, cpsStmts, "if (!$1) goto $2;$n",
"br i1 $1, label %LOC$3, label %$2$n" & "LOC$3: $n",
[rdLoc(a), Lelse, toRope(p.labels)])
when not newScopeForIf: startBlock(p)
genStmts(p, it.sons[1])
endBlock(p)
if sonsLen(n) > 1:

View File

@@ -7,13 +7,14 @@
# distribution, for details about the copyright.
#
import
import
os, lists, strutils, strtabs
const
hasTinyCBackend* = defined(tinyc)
useEffectSystem* = true
hasFFI* = defined(useFFI)
newScopeForIf* = false # XXX activate for 0.9.4
type # please make sure we have under 32 options
# (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 =
# like newSymS, but considers gensym'ed symbols
if n.kind == nkSym:
if n.kind == nkSym:
result = n.sym
InternalAssert sfGenSym in result.flags
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):
var it = n.sons[i]
if it.len == 2:
openScope(c.tab)
when newScopeForIf: openScope(c.tab)
it.sons[0] = forceBool(c, semExprWithType(c, it.sons[0]))
when not newScopeForIf: openScope(c.tab)
it.sons[1] = semExprBranch(c, it.sons[1])
typ = commonType(typ, it.sons[1].typ)
closeScope(c.tab)

View File

@@ -1918,7 +1918,9 @@ the corresponding *then* block:
else:
# '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

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"):
if kind == pcDir:
let mainfile = findMainFile(dir)
compileSingleTest(r, mainfile, options)
if mainfile != ".nim":
compileSingleTest(r, mainfile, options)
proc compileSpecialTests(r: var TResults, options: string) =
compileRodFiles(r, options)