slices are first class citizens
This commit is contained in:
parent
1985ac6995
commit
8dda362fa6
12 changed files with 177 additions and 127 deletions
20
build.bat
20
build.bat
|
|
@ -65,8 +65,8 @@ ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/streams.c -o build/1_1/streams.o
|
||||||
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/streams.c -o build/1_1/streams.o
|
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/streams.c -o build/1_1/streams.o
|
||||||
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/wordrecg.c -o build/1_1/wordrecg.o
|
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/wordrecg.c -o build/1_1/wordrecg.o
|
||||||
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/wordrecg.c -o build/1_1/wordrecg.o
|
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/wordrecg.c -o build/1_1/wordrecg.o
|
||||||
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/scanner.c -o build/1_1/scanner.o
|
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/lexer.c -o build/1_1/lexer.o
|
||||||
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/scanner.c -o build/1_1/scanner.o
|
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/lexer.c -o build/1_1/lexer.o
|
||||||
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/lexbase.c -o build/1_1/lexbase.o
|
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/lexbase.c -o build/1_1/lexbase.o
|
||||||
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/lexbase.c -o build/1_1/lexbase.o
|
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/lexbase.c -o build/1_1/lexbase.o
|
||||||
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/llstream.c -o build/1_1/llstream.o
|
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/llstream.c -o build/1_1/llstream.o
|
||||||
|
|
@ -77,16 +77,16 @@ ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/main.c -o build/1_1/main.o
|
||||||
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/main.c -o build/1_1/main.o
|
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/main.c -o build/1_1/main.o
|
||||||
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/syntaxes.c -o build/1_1/syntaxes.o
|
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/syntaxes.c -o build/1_1/syntaxes.o
|
||||||
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/syntaxes.c -o build/1_1/syntaxes.o
|
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/syntaxes.c -o build/1_1/syntaxes.o
|
||||||
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/pnimsyn.c -o build/1_1/pnimsyn.o
|
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/parser.c -o build/1_1/parser.o
|
||||||
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/pnimsyn.c -o build/1_1/pnimsyn.o
|
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/parser.c -o build/1_1/parser.o
|
||||||
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/pbraces.c -o build/1_1/pbraces.o
|
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/pbraces.c -o build/1_1/pbraces.o
|
||||||
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/pbraces.c -o build/1_1/pbraces.o
|
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/pbraces.c -o build/1_1/pbraces.o
|
||||||
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/ptmplsyn.c -o build/1_1/ptmplsyn.o
|
|
||||||
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/ptmplsyn.c -o build/1_1/ptmplsyn.o
|
|
||||||
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/rnimsyn.c -o build/1_1/rnimsyn.o
|
|
||||||
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/rnimsyn.c -o build/1_1/rnimsyn.o
|
|
||||||
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/filters.c -o build/1_1/filters.o
|
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/filters.c -o build/1_1/filters.o
|
||||||
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/filters.c -o build/1_1/filters.o
|
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/filters.c -o build/1_1/filters.o
|
||||||
|
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/renderer.c -o build/1_1/renderer.o
|
||||||
|
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/renderer.c -o build/1_1/renderer.o
|
||||||
|
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/filter_tmpl.c -o build/1_1/filter_tmpl.o
|
||||||
|
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/filter_tmpl.c -o build/1_1/filter_tmpl.o
|
||||||
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/rodread.c -o build/1_1/rodread.o
|
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/rodread.c -o build/1_1/rodread.o
|
||||||
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/rodread.c -o build/1_1/rodread.o
|
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/rodread.c -o build/1_1/rodread.o
|
||||||
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/rodwrite.c -o build/1_1/rodwrite.o
|
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/rodwrite.c -o build/1_1/rodwrite.o
|
||||||
|
|
@ -152,8 +152,8 @@ ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/transf.c -o build/1_1/transf.o
|
||||||
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/parseopt.c -o build/1_1/parseopt.o
|
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/parseopt.c -o build/1_1/parseopt.o
|
||||||
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/parseopt.c -o build/1_1/parseopt.o
|
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/parseopt.c -o build/1_1/parseopt.o
|
||||||
|
|
||||||
ECHO %LINKER% %LINK_FLAGS% -o bin\nimrod.exe build/1_1/nim__dat.o build/1_1/system.o build/1_1/nimrod.o build/1_1/times.o build/1_1/strutils.o build/1_1/parseutils.o build/1_1/winlean.o build/1_1/commands.o build/1_1/os.o build/1_1/msgs.o build/1_1/options.o build/1_1/lists.o build/1_1/nstrtabs.o build/1_1/nhashes.o build/1_1/nversion.o build/1_1/condsyms.o build/1_1/ast.o build/1_1/crc.o build/1_1/ropes.o build/1_1/platform.o build/1_1/idents.o build/1_1/astalgo.o build/1_1/rodutils.o build/1_1/extccomp.o build/1_1/osproc.o build/1_1/strtabs.o build/1_1/hashes.o build/1_1/streams.o build/1_1/wordrecg.o build/1_1/scanner.o build/1_1/lexbase.o build/1_1/llstream.o build/1_1/nimconf.o build/1_1/main.o build/1_1/syntaxes.o build/1_1/pnimsyn.o build/1_1/pbraces.o build/1_1/ptmplsyn.o build/1_1/rnimsyn.o build/1_1/filters.o build/1_1/rodread.o build/1_1/rodwrite.o build/1_1/passes.o build/1_1/types.o build/1_1/trees.o build/1_1/math.o build/1_1/magicsys.o build/1_1/nimsets.o build/1_1/bitsets.o build/1_1/importer.o build/1_1/lookups.o build/1_1/semdata.o build/1_1/treetab.o build/1_1/sem.o build/1_1/evals.o build/1_1/semfold.o build/1_1/procfind.o build/1_1/pragmas.o build/1_1/semtypinst.o build/1_1/sigmatch.o build/1_1/suggest.o build/1_1/docgen.o build/1_1/rst.o build/1_1/highlite.o build/1_1/cgen.o build/1_1/ccgutils.o build/1_1/cgmeth.o build/1_1/ecmasgen.o build/1_1/passaux.o build/1_1/depends.o build/1_1/transf.o build/1_1/parseopt.o
|
ECHO %LINKER% %LINK_FLAGS% -o bin\nimrod.exe build/1_1/nim__dat.o build/1_1/system.o build/1_1/nimrod.o build/1_1/times.o build/1_1/strutils.o build/1_1/parseutils.o build/1_1/winlean.o build/1_1/commands.o build/1_1/os.o build/1_1/msgs.o build/1_1/options.o build/1_1/lists.o build/1_1/nstrtabs.o build/1_1/nhashes.o build/1_1/nversion.o build/1_1/condsyms.o build/1_1/ast.o build/1_1/crc.o build/1_1/ropes.o build/1_1/platform.o build/1_1/idents.o build/1_1/astalgo.o build/1_1/rodutils.o build/1_1/extccomp.o build/1_1/osproc.o build/1_1/strtabs.o build/1_1/hashes.o build/1_1/streams.o build/1_1/wordrecg.o build/1_1/lexer.o build/1_1/lexbase.o build/1_1/llstream.o build/1_1/nimconf.o build/1_1/main.o build/1_1/syntaxes.o build/1_1/parser.o build/1_1/pbraces.o build/1_1/filters.o build/1_1/renderer.o build/1_1/filter_tmpl.o build/1_1/rodread.o build/1_1/rodwrite.o build/1_1/passes.o build/1_1/types.o build/1_1/trees.o build/1_1/math.o build/1_1/magicsys.o build/1_1/nimsets.o build/1_1/bitsets.o build/1_1/importer.o build/1_1/lookups.o build/1_1/semdata.o build/1_1/treetab.o build/1_1/sem.o build/1_1/evals.o build/1_1/semfold.o build/1_1/procfind.o build/1_1/pragmas.o build/1_1/semtypinst.o build/1_1/sigmatch.o build/1_1/suggest.o build/1_1/docgen.o build/1_1/rst.o build/1_1/highlite.o build/1_1/cgen.o build/1_1/ccgutils.o build/1_1/cgmeth.o build/1_1/ecmasgen.o build/1_1/passaux.o build/1_1/depends.o build/1_1/transf.o build/1_1/parseopt.o
|
||||||
%LINKER% %LINK_FLAGS% -o bin\nimrod.exe build/1_1/nim__dat.o build/1_1/system.o build/1_1/nimrod.o build/1_1/times.o build/1_1/strutils.o build/1_1/parseutils.o build/1_1/winlean.o build/1_1/commands.o build/1_1/os.o build/1_1/msgs.o build/1_1/options.o build/1_1/lists.o build/1_1/nstrtabs.o build/1_1/nhashes.o build/1_1/nversion.o build/1_1/condsyms.o build/1_1/ast.o build/1_1/crc.o build/1_1/ropes.o build/1_1/platform.o build/1_1/idents.o build/1_1/astalgo.o build/1_1/rodutils.o build/1_1/extccomp.o build/1_1/osproc.o build/1_1/strtabs.o build/1_1/hashes.o build/1_1/streams.o build/1_1/wordrecg.o build/1_1/scanner.o build/1_1/lexbase.o build/1_1/llstream.o build/1_1/nimconf.o build/1_1/main.o build/1_1/syntaxes.o build/1_1/pnimsyn.o build/1_1/pbraces.o build/1_1/ptmplsyn.o build/1_1/rnimsyn.o build/1_1/filters.o build/1_1/rodread.o build/1_1/rodwrite.o build/1_1/passes.o build/1_1/types.o build/1_1/trees.o build/1_1/math.o build/1_1/magicsys.o build/1_1/nimsets.o build/1_1/bitsets.o build/1_1/importer.o build/1_1/lookups.o build/1_1/semdata.o build/1_1/treetab.o build/1_1/sem.o build/1_1/evals.o build/1_1/semfold.o build/1_1/procfind.o build/1_1/pragmas.o build/1_1/semtypinst.o build/1_1/sigmatch.o build/1_1/suggest.o build/1_1/docgen.o build/1_1/rst.o build/1_1/highlite.o build/1_1/cgen.o build/1_1/ccgutils.o build/1_1/cgmeth.o build/1_1/ecmasgen.o build/1_1/passaux.o build/1_1/depends.o build/1_1/transf.o build/1_1/parseopt.o
|
%LINKER% %LINK_FLAGS% -o bin\nimrod.exe build/1_1/nim__dat.o build/1_1/system.o build/1_1/nimrod.o build/1_1/times.o build/1_1/strutils.o build/1_1/parseutils.o build/1_1/winlean.o build/1_1/commands.o build/1_1/os.o build/1_1/msgs.o build/1_1/options.o build/1_1/lists.o build/1_1/nstrtabs.o build/1_1/nhashes.o build/1_1/nversion.o build/1_1/condsyms.o build/1_1/ast.o build/1_1/crc.o build/1_1/ropes.o build/1_1/platform.o build/1_1/idents.o build/1_1/astalgo.o build/1_1/rodutils.o build/1_1/extccomp.o build/1_1/osproc.o build/1_1/strtabs.o build/1_1/hashes.o build/1_1/streams.o build/1_1/wordrecg.o build/1_1/lexer.o build/1_1/lexbase.o build/1_1/llstream.o build/1_1/nimconf.o build/1_1/main.o build/1_1/syntaxes.o build/1_1/parser.o build/1_1/pbraces.o build/1_1/filters.o build/1_1/renderer.o build/1_1/filter_tmpl.o build/1_1/rodread.o build/1_1/rodwrite.o build/1_1/passes.o build/1_1/types.o build/1_1/trees.o build/1_1/math.o build/1_1/magicsys.o build/1_1/nimsets.o build/1_1/bitsets.o build/1_1/importer.o build/1_1/lookups.o build/1_1/semdata.o build/1_1/treetab.o build/1_1/sem.o build/1_1/evals.o build/1_1/semfold.o build/1_1/procfind.o build/1_1/pragmas.o build/1_1/semtypinst.o build/1_1/sigmatch.o build/1_1/suggest.o build/1_1/docgen.o build/1_1/rst.o build/1_1/highlite.o build/1_1/cgen.o build/1_1/ccgutils.o build/1_1/cgmeth.o build/1_1/ecmasgen.o build/1_1/passaux.o build/1_1/depends.o build/1_1/transf.o build/1_1/parseopt.o
|
||||||
|
|
||||||
ECHO SUCCESS
|
ECHO SUCCESS
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,8 @@ proc newIntNodeP(kind: TNodeKind, intVal: BiggestInt, p: TParser): PNode =
|
||||||
result = newNodeP(kind, p)
|
result = newNodeP(kind, p)
|
||||||
result.intVal = intVal
|
result.intVal = intVal
|
||||||
|
|
||||||
proc newFloatNodeP(kind: TNodeKind, floatVal: BiggestFloat, p: TParser): PNode =
|
proc newFloatNodeP(kind: TNodeKind, floatVal: BiggestFloat,
|
||||||
|
p: TParser): PNode =
|
||||||
result = newNodeP(kind, p)
|
result = newNodeP(kind, p)
|
||||||
result.floatVal = floatVal
|
result.floatVal = floatVal
|
||||||
|
|
||||||
|
|
@ -147,16 +148,18 @@ proc getPrecedence(tok: PToken): int =
|
||||||
case tok.tokType
|
case tok.tokType
|
||||||
of tkOpr:
|
of tkOpr:
|
||||||
case tok.ident.s[0]
|
case tok.ident.s[0]
|
||||||
of '$', '^': result = 7
|
of '$', '^': result = 9
|
||||||
of '*', '%', '/', '\\': result = 6
|
of '*', '%', '/', '\\': result = 8
|
||||||
of '+', '-', '~', '|': result = 5
|
of '+', '-', '~', '|': result = 7
|
||||||
of '&': result = 4
|
of '&': result = 6
|
||||||
of '=', '<', '>', '!': result = 3
|
of '=', '<', '>', '!': result = 4
|
||||||
else: result = 0
|
of '.': result = 5
|
||||||
of tkDiv, tkMod, tkShl, tkShr: result = 6
|
else: result = 1
|
||||||
of tkIn, tkNotIn, tkIs, tkIsNot: result = 3
|
of tkDiv, tkMod, tkShl, tkShr: result = 8
|
||||||
of tkAnd: result = 2
|
of tkIn, tkNotIn, tkIs, tkIsNot, tkNot: result = 4
|
||||||
of tkOr, tkXor: result = 1
|
of tkDotDot: result = 5
|
||||||
|
of tkAnd: result = 3
|
||||||
|
of tkOr, tkXor: result = 2
|
||||||
else: result = - 10
|
else: result = - 10
|
||||||
|
|
||||||
proc isOperator(tok: PToken): bool =
|
proc isOperator(tok: PToken): bool =
|
||||||
|
|
@ -202,7 +205,7 @@ proc parseSymbol(p: var TParser): PNode =
|
||||||
addSon(result, newIdentNodeP(getIdent("()"), p))
|
addSon(result, newIdentNodeP(getIdent("()"), p))
|
||||||
getTok(p)
|
getTok(p)
|
||||||
eat(p, tkParRi)
|
eat(p, tkParRi)
|
||||||
of tokKeywordLow..tokKeywordHigh, tkSymbol, tkOpr:
|
of tokKeywordLow..tokKeywordHigh, tkSymbol, tkOpr, tkDotDot:
|
||||||
var id = p.tok.ident
|
var id = p.tok.ident
|
||||||
getTok(p)
|
getTok(p)
|
||||||
if p.tok.tokType == tkEquals:
|
if p.tok.tokType == tkEquals:
|
||||||
|
|
@ -494,7 +497,7 @@ proc identOrLiteral(p: var TParser): PNode =
|
||||||
|
|
||||||
proc primary(p: var TParser): PNode =
|
proc primary(p: var TParser): PNode =
|
||||||
# prefix operator?
|
# prefix operator?
|
||||||
if (p.tok.tokType == tkNot) or (p.tok.tokType == tkOpr):
|
if isOperator(p.tok):
|
||||||
result = newNodeP(nkPrefix, p)
|
result = newNodeP(nkPrefix, p)
|
||||||
var a = newIdentNodeP(p.tok.ident, p)
|
var a = newIdentNodeP(p.tok.ident, p)
|
||||||
addSon(result, a)
|
addSon(result, a)
|
||||||
|
|
@ -553,18 +556,8 @@ proc lowestExprAux(p: var TParser, v: var PNode, limit: int): PToken =
|
||||||
opPrec = getPrecedence(nextop)
|
opPrec = getPrecedence(nextop)
|
||||||
result = op # return first untreated operator
|
result = op # return first untreated operator
|
||||||
|
|
||||||
proc otherExpr(p: var TParser): PNode =
|
|
||||||
discard lowestExprAux(p, result, - 1)
|
|
||||||
|
|
||||||
proc lowestExpr(p: var TParser): PNode =
|
proc lowestExpr(p: var TParser): PNode =
|
||||||
result = otherExpr(p)
|
discard lowestExprAux(p, result, - 1)
|
||||||
while p.tok.tokType == tkDotDot:
|
|
||||||
getTok(p)
|
|
||||||
optInd(p, result)
|
|
||||||
var a = result
|
|
||||||
result = newNodeP(nkRange, p)
|
|
||||||
addSon(result, a)
|
|
||||||
addSon(result, otherExpr(p))
|
|
||||||
|
|
||||||
proc parseIfExpr(p: var TParser): PNode =
|
proc parseIfExpr(p: var TParser): PNode =
|
||||||
result = newNodeP(nkIfExpr, p)
|
result = newNodeP(nkIfExpr, p)
|
||||||
|
|
|
||||||
|
|
@ -828,15 +828,20 @@ proc semSetConstr(c: PContext, n: PNode): PNode =
|
||||||
# only semantic checking for all elements, later type checking:
|
# only semantic checking for all elements, later type checking:
|
||||||
var typ: PType = nil
|
var typ: PType = nil
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
if n.sons[i].kind == nkRange:
|
if isRange(n.sons[i]):
|
||||||
checkSonsLen(n.sons[i], 2)
|
checkSonsLen(n.sons[i], 3)
|
||||||
n.sons[i].sons[0] = semExprWithType(c, n.sons[i].sons[0])
|
|
||||||
n.sons[i].sons[1] = semExprWithType(c, n.sons[i].sons[1])
|
n.sons[i].sons[1] = semExprWithType(c, n.sons[i].sons[1])
|
||||||
|
n.sons[i].sons[2] = semExprWithType(c, n.sons[i].sons[2])
|
||||||
if typ == nil:
|
if typ == nil:
|
||||||
|
typ = skipTypes(n.sons[i].sons[1].typ,
|
||||||
|
{tyGenericInst, tyVar, tyOrdinal})
|
||||||
|
n.sons[i].typ = n.sons[i].sons[2].typ # range node needs type too
|
||||||
|
elif n.sons[i].kind == nkRange:
|
||||||
|
# already semchecked
|
||||||
|
if typ == nil:
|
||||||
typ = skipTypes(n.sons[i].sons[0].typ,
|
typ = skipTypes(n.sons[i].sons[0].typ,
|
||||||
{tyGenericInst, tyVar, tyOrdinal})
|
{tyGenericInst, tyVar, tyOrdinal})
|
||||||
n.sons[i].typ = n.sons[i].sons[1].typ # range node needs type too
|
else:
|
||||||
else:
|
|
||||||
n.sons[i] = semExprWithType(c, n.sons[i])
|
n.sons[i] = semExprWithType(c, n.sons[i])
|
||||||
if typ == nil:
|
if typ == nil:
|
||||||
typ = skipTypes(n.sons[i].typ, {tyGenericInst, tyVar, tyOrdinal})
|
typ = skipTypes(n.sons[i].typ, {tyGenericInst, tyVar, tyOrdinal})
|
||||||
|
|
@ -848,11 +853,12 @@ proc semSetConstr(c: PContext, n: PNode): PNode =
|
||||||
addSon(result.typ, typ)
|
addSon(result.typ, typ)
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
var m: PNode
|
var m: PNode
|
||||||
if n.sons[i].kind == nkRange:
|
if isRange(n.sons[i]):
|
||||||
m = newNodeI(nkRange, n.sons[i].info)
|
m = newNodeI(nkRange, n.sons[i].info)
|
||||||
addSon(m, fitNode(c, typ, n.sons[i].sons[0]))
|
|
||||||
addSon(m, fitNode(c, typ, n.sons[i].sons[1]))
|
addSon(m, fitNode(c, typ, n.sons[i].sons[1]))
|
||||||
else:
|
addSon(m, fitNode(c, typ, n.sons[i].sons[2]))
|
||||||
|
elif n.sons[i].kind == nkRange: m = n.sons[i] # already semchecked
|
||||||
|
else:
|
||||||
m = fitNode(c, typ, n.sons[i])
|
m = fitNode(c, typ, n.sons[i])
|
||||||
addSon(result, m)
|
addSon(result, m)
|
||||||
|
|
||||||
|
|
@ -1086,7 +1092,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
checkMinSonsLen(n, 2)
|
checkMinSonsLen(n, 2)
|
||||||
of nkSymChoice:
|
of nkSymChoice:
|
||||||
GlobalError(n.info, errExprXAmbiguous, renderTree(n, {renderNoComments}))
|
GlobalError(n.info, errExprXAmbiguous, renderTree(n, {renderNoComments}))
|
||||||
else:
|
else:
|
||||||
#InternalError(n.info, nodeKindToStr[n.kind]);
|
GlobalError(n.info, errInvalidExpressionX,
|
||||||
GlobalError(n.info, errInvalidExpressionX, renderTree(n, {renderNoComments}))
|
renderTree(n, {renderNoComments}))
|
||||||
incl(result.flags, nfSem)
|
incl(result.flags, nfSem)
|
||||||
|
|
|
||||||
|
|
@ -339,11 +339,11 @@ proc semConst(c: PContext, n: PNode): PNode =
|
||||||
if a.sons[1].kind != nkEmpty: typ = semTypeNode(c, a.sons[1], nil)
|
if a.sons[1].kind != nkEmpty: typ = semTypeNode(c, a.sons[1], nil)
|
||||||
var def = semAndEvalConstExpr(c, a.sons[2])
|
var def = semAndEvalConstExpr(c, a.sons[2])
|
||||||
# check type compability between def.typ and typ:
|
# check type compability between def.typ and typ:
|
||||||
if (typ != nil):
|
if typ != nil:
|
||||||
def = fitRemoveHiddenConv(c, typ, def)
|
def = fitRemoveHiddenConv(c, typ, def)
|
||||||
else:
|
else:
|
||||||
typ = def.typ
|
typ = def.typ
|
||||||
if not typeAllowed(typ, skConst):
|
if not typeAllowed(typ, skConst):
|
||||||
GlobalError(a.info, errXisNoType, typeToString(typ))
|
GlobalError(a.info, errXisNoType, typeToString(typ))
|
||||||
v.typ = typ
|
v.typ = typ
|
||||||
v.ast = def # no need to copy
|
v.ast = def # no need to copy
|
||||||
|
|
@ -423,25 +423,12 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
|
||||||
var b = newNodeI(nkBreakStmt, n.info)
|
var b = newNodeI(nkBreakStmt, n.info)
|
||||||
b.add(ast.emptyNode)
|
b.add(ast.emptyNode)
|
||||||
stmts.add(b)
|
stmts.add(b)
|
||||||
|
|
||||||
proc createCountupNode(c: PContext, rangeNode: PNode): PNode =
|
|
||||||
# convert ``in 3..5`` to ``in countup(3, 5)``
|
|
||||||
checkSonsLen(rangeNode, 2)
|
|
||||||
result = newNodeI(nkCall, rangeNode.info)
|
|
||||||
var countUp = StrTableGet(magicsys.systemModule.Tab, getIdent"countup")
|
|
||||||
if countUp == nil: GlobalError(rangeNode.info, errSystemNeeds, "countup")
|
|
||||||
newSons(result, 3)
|
|
||||||
result.sons[0] = newSymNode(countup)
|
|
||||||
result.sons[1] = rangeNode.sons[0]
|
|
||||||
result.sons[2] = rangeNode.sons[1]
|
|
||||||
|
|
||||||
proc semFor(c: PContext, n: PNode): PNode =
|
proc semFor(c: PContext, n: PNode): PNode =
|
||||||
result = n
|
result = n
|
||||||
checkMinSonsLen(n, 3)
|
checkMinSonsLen(n, 3)
|
||||||
var length = sonsLen(n)
|
var length = sonsLen(n)
|
||||||
openScope(c.tab)
|
openScope(c.tab)
|
||||||
if n.sons[length-2].kind == nkRange:
|
|
||||||
n.sons[length-2] = createCountupNode(c, n.sons[length-2])
|
|
||||||
n.sons[length-2] = semExprWithType(c, n.sons[length-2], {efWantIterator})
|
n.sons[length-2] = semExprWithType(c, n.sons[length-2], {efWantIterator})
|
||||||
var call = n.sons[length-2]
|
var call = n.sons[length-2]
|
||||||
if call.kind != nkCall or call.sons[0].kind != nkSym or
|
if call.kind != nkCall or call.sons[0].kind != nkSym or
|
||||||
|
|
|
||||||
|
|
@ -116,14 +116,14 @@ proc semDistinct(c: PContext, n: PNode, prev: PType): PType =
|
||||||
else: GlobalError(n.info, errXExpectsOneTypeParam, "distinct")
|
else: GlobalError(n.info, errXExpectsOneTypeParam, "distinct")
|
||||||
|
|
||||||
proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
|
proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
|
||||||
if (n.kind != nkRange): InternalError(n.info, "semRangeAux")
|
assert IsRange(n)
|
||||||
checkSonsLen(n, 2)
|
checkSonsLen(n, 3)
|
||||||
result = newOrPrevType(tyRange, prev, c)
|
result = newOrPrevType(tyRange, prev, c)
|
||||||
result.n = newNodeI(nkRange, n.info)
|
result.n = newNodeI(nkRange, n.info)
|
||||||
if (n.sons[0].kind == nkEmpty) or (n.sons[1].kind == nkEmpty):
|
if (n[1].kind == nkEmpty) or (n[2].kind == nkEmpty):
|
||||||
GlobalError(n.Info, errRangeIsEmpty)
|
GlobalError(n.Info, errRangeIsEmpty)
|
||||||
var a = semConstExpr(c, n.sons[0])
|
var a = semConstExpr(c, n[1])
|
||||||
var b = semConstExpr(c, n.sons[1])
|
var b = semConstExpr(c, n[2])
|
||||||
if not sameType(a.typ, b.typ): GlobalError(n.info, errPureTypeMismatch)
|
if not sameType(a.typ, b.typ): GlobalError(n.info, errPureTypeMismatch)
|
||||||
if not (a.typ.kind in
|
if not (a.typ.kind in
|
||||||
{tyInt..tyInt64, tyEnum, tyBool, tyChar, tyFloat..tyFloat128}):
|
{tyInt..tyInt64, tyEnum, tyBool, tyChar, tyFloat..tyFloat128}):
|
||||||
|
|
@ -138,7 +138,7 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
|
||||||
proc semRange(c: PContext, n: PNode, prev: PType): PType =
|
proc semRange(c: PContext, n: PNode, prev: PType): PType =
|
||||||
result = nil
|
result = nil
|
||||||
if sonsLen(n) == 2:
|
if sonsLen(n) == 2:
|
||||||
if n.sons[1].kind == nkRange: result = semRangeAux(c, n.sons[1], prev)
|
if isRange(n[1]): result = semRangeAux(c, n[1], prev)
|
||||||
else: GlobalError(n.sons[0].info, errRangeExpected)
|
else: GlobalError(n.sons[0].info, errRangeExpected)
|
||||||
else:
|
else:
|
||||||
GlobalError(n.info, errXExpectsOneTypeParam, "range")
|
GlobalError(n.info, errXExpectsOneTypeParam, "range")
|
||||||
|
|
@ -148,7 +148,7 @@ proc semArray(c: PContext, n: PNode, prev: PType): PType =
|
||||||
result = newOrPrevType(tyArray, prev, c)
|
result = newOrPrevType(tyArray, prev, c)
|
||||||
if sonsLen(n) == 3:
|
if sonsLen(n) == 3:
|
||||||
# 3 = length(array indx base)
|
# 3 = length(array indx base)
|
||||||
if n.sons[1].kind == nkRange: indx = semRangeAux(c, n.sons[1], nil)
|
if isRange(n[1]): indx = semRangeAux(c, n[1], nil)
|
||||||
else: indx = semTypeNode(c, n.sons[1], nil)
|
else: indx = semTypeNode(c, n.sons[1], nil)
|
||||||
addSon(result, indx)
|
addSon(result, indx)
|
||||||
if indx.kind == tyGenericInst: indx = lastSon(indx)
|
if indx.kind == tyGenericInst: indx = lastSon(indx)
|
||||||
|
|
@ -276,26 +276,26 @@ proc checkForOverlap(c: PContext, t, ex: PNode, branchIndex: int) =
|
||||||
if overlap(t.sons[i].sons[j], ex):
|
if overlap(t.sons[i].sons[j], ex):
|
||||||
LocalError(ex.info, errDuplicateCaseLabel)
|
LocalError(ex.info, errDuplicateCaseLabel)
|
||||||
|
|
||||||
proc semBranchExpr(c: PContext, t: PNode, ex: var PNode) =
|
proc semBranchExpr(c: PContext, t, e: PNode): PNode =
|
||||||
ex = semConstExpr(c, ex)
|
result = semConstExpr(c, e)
|
||||||
checkMinSonsLen(t, 1)
|
checkMinSonsLen(t, 1)
|
||||||
if (cmpTypes(t.sons[0].typ, ex.typ) <= isConvertible):
|
if cmpTypes(t.sons[0].typ, result.typ) <= isConvertible:
|
||||||
typeMismatch(ex, t.sons[0].typ, ex.typ)
|
typeMismatch(result, t.sons[0].typ, result.typ)
|
||||||
|
|
||||||
proc SemCaseBranch(c: PContext, t, branch: PNode, branchIndex: int,
|
proc SemCaseBranch(c: PContext, t, branch: PNode, branchIndex: int,
|
||||||
covered: var biggestInt) =
|
covered: var biggestInt) =
|
||||||
for i in countup(0, sonsLen(branch) - 2):
|
for i in countup(0, sonsLen(branch) - 2):
|
||||||
var b = branch.sons[i]
|
var b = branch.sons[i]
|
||||||
if b.kind == nkRange:
|
if isRange(b):
|
||||||
checkSonsLen(b, 2)
|
checkSonsLen(b, 3)
|
||||||
semBranchExpr(c, t, b.sons[0])
|
var r = newNodeI(nkRange, b.info)
|
||||||
semBranchExpr(c, t, b.sons[1])
|
r.add(semBranchExpr(c, t, b.sons[1]))
|
||||||
if emptyRange(b.sons[0], b.sons[1]):
|
r.add(semBranchExpr(c, t, b.sons[2]))
|
||||||
#MessageOut(renderTree(t));
|
if emptyRange(r[0], r[1]): GlobalError(b.info, errRangeIsEmpty)
|
||||||
GlobalError(b.info, errRangeIsEmpty)
|
covered = covered + getOrdValue(r[1]) - getOrdValue(r[0]) + 1
|
||||||
covered = covered + getOrdValue(b.sons[1]) - getOrdValue(b.sons[0]) + 1
|
branch.sons[i] = r
|
||||||
else:
|
else:
|
||||||
semBranchExpr(c, t, branch.sons[i]) # NOT: `b`, because of var-param!
|
branch.sons[i] = semBranchExpr(c, t, b)
|
||||||
inc(covered)
|
inc(covered)
|
||||||
checkForOverlap(c, t, branch.sons[i], branchIndex)
|
checkForOverlap(c, t, branch.sons[i], branchIndex)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# The Nimrod Compiler
|
# The Nimrod Compiler
|
||||||
# (c) Copyright 2008 Andreas Rumpf
|
# (c) Copyright 2011 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
# tree helper routines
|
# tree helper routines
|
||||||
|
|
||||||
import
|
import
|
||||||
ast, astalgo, lexer, msgs, strutils
|
ast, astalgo, lexer, msgs, strutils, wordrecg
|
||||||
|
|
||||||
proc getMagic*(op: PNode): TMagic
|
proc getMagic*(op: PNode): TMagic
|
||||||
|
|
||||||
|
|
@ -106,7 +106,8 @@ proc getOpSym(op: PNode): PSym =
|
||||||
|
|
||||||
proc getMagic(op: PNode): TMagic =
|
proc getMagic(op: PNode): TMagic =
|
||||||
case op.kind
|
case op.kind
|
||||||
of nkCall, nkHiddenCallConv, nkCommand, nkCallStrLit:
|
of nkCall, nkHiddenCallConv, nkCommand, nkCallStrLit, nkPrefix, nkPostfix,
|
||||||
|
nkInfix:
|
||||||
case op.sons[0].Kind
|
case op.sons[0].Kind
|
||||||
of nkSym: result = op.sons[0].sym.magic
|
of nkSym: result = op.sons[0].sym.magic
|
||||||
else: result = mNone
|
else: result = mNone
|
||||||
|
|
@ -138,3 +139,8 @@ proc SwapOperands(op: PNode) =
|
||||||
var tmp = op.sons[1]
|
var tmp = op.sons[1]
|
||||||
op.sons[1] = op.sons[2]
|
op.sons[1] = op.sons[2]
|
||||||
op.sons[2] = tmp
|
op.sons[2] = tmp
|
||||||
|
|
||||||
|
proc IsRange*(n: PNode): bool {.inline.} =
|
||||||
|
result = n.kind == nkInfix and n[0].kind == nkIdent and
|
||||||
|
n[0].ident.id == ord(wDotDot)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,27 @@
|
||||||
module ::= ([COMMENT] [SAD] stmt)*
|
module ::= ([COMMENT] [SAD] stmt)*
|
||||||
|
|
||||||
comma ::= ',' [COMMENT] [IND]
|
comma ::= ',' [COMMENT] [IND]
|
||||||
operator ::= OP0 | OR | XOR | AND | OP3 | OP4 | OP5 | OP6 | OP7
|
operator ::= OP1 | OP2 | OP3 | OP4 | OP5 | OP6 | OP7 | OP8 | OP9
|
||||||
|
| 'or' | 'xor' | 'and'
|
||||||
| 'is' | 'isnot' | 'in' | 'notin'
|
| 'is' | 'isnot' | 'in' | 'notin'
|
||||||
| 'div' | 'mod' | 'shl' | 'shr' | 'not'
|
| 'div' | 'mod' | 'shl' | 'shr' | 'not' | '..'
|
||||||
|
|
||||||
prefixOperator ::= OP0 | OP3 | OP4 | OP5 | OP6 | OP7 | 'not'
|
prefixOperator ::= operator
|
||||||
|
|
||||||
optInd ::= [COMMENT] [IND]
|
optInd ::= [COMMENT] [IND]
|
||||||
optPar ::= [IND] | [SAD]
|
optPar ::= [IND] | [SAD]
|
||||||
|
|
||||||
lowestExpr ::= otherExpr ('..' optInd otherExpr)*
|
lowestExpr ::= orExpr (OP1 optInd orExpr)*
|
||||||
otherExpr ::= orExpr (OP0 optInd orExpr)*
|
orExpr ::= andExpr (OP2 optInd andExpr)*
|
||||||
orExpr ::= andExpr (OR | 'xor' optInd andExpr)*
|
andExpr ::= cmpExpr (OP3 optInd cmpExpr)*
|
||||||
andExpr ::= cmpExpr ('and' optInd cmpExpr)*
|
cmpExpr ::= sliceExpr (OP4 optInd sliceExpr)*
|
||||||
cmpExpr ::= ampExpr (OP3 | 'is' | 'isnot' | 'in' | 'notin' optInd ampExpr)*
|
sliceExpr ::= ampExpr (OP5 optInd ampExpr)*
|
||||||
ampExpr ::= plusExpr (OP4 optInd plusExpr)*
|
ampExpr ::= plusExpr (OP6 optInd plusExpr)*
|
||||||
plusExpr ::= mulExpr (OP5 optInd mulExpr)*
|
plusExpr ::= mulExpr (OP7 optInd mulExpr)*
|
||||||
mulExpr ::= dollarExpr (OP6 | 'div' | 'mod' | 'shl' | 'shr' optInd dollarExpr)*
|
mulExpr ::= dollarExpr (OP8 optInd dollarExpr)*
|
||||||
dollarExpr ::= primary (OP7 optInd primary)*
|
dollarExpr ::= primary (OP9 optInd primary)*
|
||||||
|
|
||||||
indexExpr ::= '..' [expr] | expr ['=' expr]
|
indexExpr ::= expr ['=' expr]
|
||||||
|
|
||||||
castExpr ::= 'cast' '[' optInd typeDesc optPar ']' '(' optInd expr optPar ')'
|
castExpr ::= 'cast' '[' optInd typeDesc optPar ']' '(' optInd expr optPar ')'
|
||||||
addrExpr ::= 'addr' '(' optInd expr optPar ')'
|
addrExpr ::= 'addr' '(' optInd expr optPar ')'
|
||||||
|
|
@ -120,7 +121,7 @@ caseStmt ::= 'case' expr [':'] ('of' exprList ':' stmt)*
|
||||||
('elif' expr ':' stmt)*
|
('elif' expr ':' stmt)*
|
||||||
['else' ':' stmt]
|
['else' ':' stmt]
|
||||||
whileStmt ::= 'while' expr ':' stmt
|
whileStmt ::= 'while' expr ':' stmt
|
||||||
forStmt ::= 'for' symbol (comma symbol)* 'in' expr ['..' expr] ':' stmt
|
forStmt ::= 'for' symbol (comma symbol)* 'in' expr ':' stmt
|
||||||
exceptList ::= [qualifiedIdent (comma qualifiedIdent)*]
|
exceptList ::= [qualifiedIdent (comma qualifiedIdent)*]
|
||||||
|
|
||||||
tryStmt ::= 'try' ':' stmt
|
tryStmt ::= 'try' ':' stmt
|
||||||
|
|
|
||||||
|
|
@ -346,29 +346,38 @@ notation:
|
||||||
``0B0_10001110100_0000101001000111101011101111111011000101001101001001'f64``
|
``0B0_10001110100_0000101001000111101011101111111011000101001101001001'f64``
|
||||||
is approximately 1.72826e35 according to the IEEE floating point standard.
|
is approximately 1.72826e35 according to the IEEE floating point standard.
|
||||||
|
|
||||||
|
|
||||||
|
Operators
|
||||||
|
---------
|
||||||
|
|
||||||
|
In Nimrod one can define his own operators. An `operator`:idx: is any
|
||||||
|
combination of the following characters::
|
||||||
|
|
||||||
|
= + - * / < >
|
||||||
|
@ $ ~ & % |
|
||||||
|
! ? ^ . : \
|
||||||
|
|
||||||
|
These keywords are also operators:
|
||||||
|
``and or not xor shl shr div mod in notin is isnot``.
|
||||||
|
|
||||||
|
`=`:tok:, `:`:tok:, `::`:tok: are not available as general operators; they
|
||||||
|
are used for other notational purposes.
|
||||||
|
|
||||||
|
``*:`` is as a special case the two tokens `*`:tok: and `:`:tok:
|
||||||
|
(to support ``var v*: T``).
|
||||||
|
|
||||||
|
|
||||||
Other tokens
|
Other tokens
|
||||||
------------
|
------------
|
||||||
|
|
||||||
The following strings denote other tokens::
|
The following strings denote other tokens::
|
||||||
|
|
||||||
( ) { } [ ] , ; [. .] {. .} (. .)
|
` ( ) { } [ ] , ; [. .] {. .} (. .)
|
||||||
: = ^ .. `
|
|
||||||
|
|
||||||
`..`:tok: takes precedence over other tokens that contain a dot: `{..}`:tok: are
|
The `slice`:idx: operator `..`:tok: takes precedence over other tokens that
|
||||||
the three tokens `{`:tok:, `..`:tok:, `}`:tok: and not the two tokens
|
contain a dot: `{..}`:tok: are the three tokens `{`:tok:, `..`:tok:, `}`:tok:
|
||||||
`{.`:tok:, `.}`:tok:.
|
and not the two tokens `{.`:tok:, `.}`:tok:.
|
||||||
|
|
||||||
In Nimrod one can define his own operators. An `operator`:idx: is any
|
|
||||||
combination of the following characters that is not listed above::
|
|
||||||
|
|
||||||
+ - * / < >
|
|
||||||
= @ $ ~ & %
|
|
||||||
! ? ^ . | \
|
|
||||||
|
|
||||||
These keywords are also operators:
|
|
||||||
``and or not xor shl shr div mod in notin is isnot``.
|
|
||||||
|
|
||||||
|
|
||||||
Syntax
|
Syntax
|
||||||
|
|
@ -378,7 +387,7 @@ This section lists Nimrod's standard syntax in ENBF. How the parser receives
|
||||||
indentation tokens is already described in the `Lexical Analysis`_ section.
|
indentation tokens is already described in the `Lexical Analysis`_ section.
|
||||||
|
|
||||||
Nimrod allows user-definable operators.
|
Nimrod allows user-definable operators.
|
||||||
Binary operators have 8 different levels of precedence. For user-defined
|
Binary operators have 9 different levels of precedence. For user-defined
|
||||||
operators, the precedence depends on the first character the operator consists
|
operators, the precedence depends on the first character the operator consists
|
||||||
of. All binary operators are left-associative, except binary operators starting
|
of. All binary operators are left-associative, except binary operators starting
|
||||||
with (or only consisting of) ``^``.
|
with (or only consisting of) ``^``.
|
||||||
|
|
@ -386,14 +395,15 @@ with (or only consisting of) ``^``.
|
||||||
================ ============================================== ================== ===============
|
================ ============================================== ================== ===============
|
||||||
Precedence level Operators First characters Terminal symbol
|
Precedence level Operators First characters Terminal symbol
|
||||||
================ ============================================== ================== ===============
|
================ ============================================== ================== ===============
|
||||||
7 (highest) ``$ ^`` OP7
|
9 (highest) ``$ ^`` OP9
|
||||||
6 ``* / div mod shl shr %`` ``* % \ /`` OP6
|
8 ``* / div mod shl shr %`` ``* % \ /`` OP8
|
||||||
5 ``+ -`` ``+ ~ |`` OP5
|
7 ``+ -`` ``+ ~ |`` OP7
|
||||||
4 ``&`` ``&`` OP4
|
6 ``&`` ``&`` OP6
|
||||||
3 ``== <= < >= > != in not_in is isnot`` ``= < > !`` OP3
|
5 ``..`` ``.`` OP5
|
||||||
2 ``and`` OP2
|
4 ``== <= < >= > != in not_in is isnot not`` ``= < > !`` OP4
|
||||||
1 ``or xor`` OP1
|
3 ``and`` OP3
|
||||||
0 (lowest) ``? @ ` : .`` OP0
|
2 ``or xor`` OP2
|
||||||
|
1 (lowest) `` @ : ? `` OP1
|
||||||
================ ============================================== ================== ===============
|
================ ============================================== ================== ===============
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2948,7 +2958,11 @@ string expressions in general:
|
||||||
proc myImport(s: cstring) {.cdecl, importc, dynlib: getDllName().}
|
proc myImport(s: cstring) {.cdecl, importc, dynlib: getDllName().}
|
||||||
|
|
||||||
**Note**: Patterns like ``libtcl(|8.5|8.4).so`` are only supported in constant
|
**Note**: Patterns like ``libtcl(|8.5|8.4).so`` are only supported in constant
|
||||||
strings, because they are precompiled.
|
strings, because they are precompiled.
|
||||||
|
|
||||||
|
**Note**: Passing variables to the ``dynlib`` pragma will fail at runtime
|
||||||
|
because of order of initialization problems.
|
||||||
|
|
||||||
|
|
||||||
Dynlib pragma for export
|
Dynlib pragma for export
|
||||||
------------------------
|
------------------------
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,26 @@ type
|
||||||
seq*{.magic: "Seq".}[T] ## Generic type to construct sequences.
|
seq*{.magic: "Seq".}[T] ## Generic type to construct sequences.
|
||||||
set*{.magic: "Set".}[T] ## Generic type to construct bit sets.
|
set*{.magic: "Set".}[T] ## Generic type to construct bit sets.
|
||||||
|
|
||||||
|
type
|
||||||
|
TSlice* {.final, pure.}[T] = object ## builtin slice type
|
||||||
|
a*, b*: T ## the bounds
|
||||||
|
|
||||||
|
proc `..`*[T](a, b: T): TSlice[T] {.noSideEffect, inline.} =
|
||||||
|
## `slice`:idx: operator that constructs an interval ``[a, b]``, both `a`
|
||||||
|
## and `b` are inclusive. Slices can also be used in the set constructor
|
||||||
|
## and in ordinal case statements, but then they are special-cased by the
|
||||||
|
## compiler.
|
||||||
|
result.a = a
|
||||||
|
result.b = b
|
||||||
|
|
||||||
|
proc `..`*[T](b: T): TSlice[T] {.noSideEffect, inline.} =
|
||||||
|
## `slice`:idx: operator that constructs an interval ``[low(T), b]``
|
||||||
|
result.a = low(b)
|
||||||
|
result.b = b
|
||||||
|
|
||||||
|
proc contains*[T](s: TSlice[T], value: T): bool {.noSideEffect, inline.} =
|
||||||
|
result = value >= s.a and value <= s.b
|
||||||
|
|
||||||
when not defined(EcmaScript) and not defined(NimrodVM):
|
when not defined(EcmaScript) and not defined(NimrodVM):
|
||||||
type
|
type
|
||||||
TGenericSeq {.compilerproc, pure.} = object
|
TGenericSeq {.compilerproc, pure.} = object
|
||||||
|
|
@ -1040,6 +1060,13 @@ iterator countup*[S, T](a: S, b: T, step = 1): T {.inline.} =
|
||||||
yield res
|
yield res
|
||||||
inc(res, step)
|
inc(res, step)
|
||||||
|
|
||||||
|
iterator `..`*[S, T](a: S, b: T): T {.inline.} =
|
||||||
|
## An alias for `countup`.
|
||||||
|
var res: T = a
|
||||||
|
while res <= b:
|
||||||
|
yield res
|
||||||
|
inc res
|
||||||
|
|
||||||
proc min*(x, y: int): int {.magic: "MinI", noSideEffect.}
|
proc min*(x, y: int): int {.magic: "MinI", noSideEffect.}
|
||||||
proc min*(x, y: int8): int8 {.magic: "MinI", noSideEffect.}
|
proc min*(x, y: int8): int8 {.magic: "MinI", noSideEffect.}
|
||||||
proc min*(x, y: int16): int16 {.magic: "MinI", noSideEffect.}
|
proc min*(x, y: int16): int16 {.magic: "MinI", noSideEffect.}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ elif defined(macosx):
|
||||||
dllName = "libtcl(8.5|8.4|8.3|8.2|8.1).dylib"
|
dllName = "libtcl(8.5|8.4|8.3|8.2|8.1).dylib"
|
||||||
else:
|
else:
|
||||||
const
|
const
|
||||||
dllName = "libtcl(8.5|8.4|8.3|8.2|8.1).so.(1|0)"
|
dllName = "libtcl(8.5|8.4|8.3|8.2|8.1).so(|.1|.0)"
|
||||||
const
|
const
|
||||||
TCL_DESTROYED* = 0xDEADDEAD
|
TCL_DESTROYED* = 0xDEADDEAD
|
||||||
TCL_OK* = 0
|
TCL_OK* = 0
|
||||||
|
|
|
||||||
16
tests/accept/compile/ttableconstr.nim
Normal file
16
tests/accept/compile/ttableconstr.nim
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
# Test if the new table constructor syntax works:
|
||||||
|
|
||||||
|
template ignoreExpr(e: expr): stmt =
|
||||||
|
nil
|
||||||
|
|
||||||
|
# test first class '..' syntactical citizen:
|
||||||
|
ignoreExpr x <> 2..4
|
||||||
|
# test table constructor:
|
||||||
|
ignoreExpr({:})
|
||||||
|
ignoreExpr({2: 3, "key": "value"})
|
||||||
|
|
||||||
|
# NEW:
|
||||||
|
assert 56 in 50..100
|
||||||
|
|
||||||
|
assert 56 in ..60
|
||||||
|
|
||||||
2
todo.txt
2
todo.txt
|
|
@ -1,4 +1,5 @@
|
||||||
- clean up the tests!
|
- clean up the tests!
|
||||||
|
- fake-consts and semantic checking for table constructor
|
||||||
|
|
||||||
|
|
||||||
High priority (version 0.9.0)
|
High priority (version 0.9.0)
|
||||||
|
|
@ -28,7 +29,6 @@ To implement
|
||||||
|
|
||||||
* hash tables and sets; count tables; ordered dicts
|
* hash tables and sets; count tables; ordered dicts
|
||||||
* distinct types for array/seq indexes
|
* distinct types for array/seq indexes
|
||||||
* constant sequences
|
|
||||||
|
|
||||||
* implement closures for the C code generator
|
* implement closures for the C code generator
|
||||||
* GC: marker procs for native Nimrod GC and Boehm GC
|
* GC: marker procs for native Nimrod GC and Boehm GC
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue