bugfix: inconsequent tuple usage

This commit is contained in:
Andreas Rumpf
2009-12-09 00:41:55 +01:00
parent bfef392460
commit f265c3e866
13 changed files with 173 additions and 486 deletions

View File

@@ -1,163 +0,0 @@
# Configuration file for the Nimrod Compiler.
# Generated by the koch.py script.
# (c) 2008 Andreas Rumpf
# Feel free to edit the default values as you need.
# You may set environment variables with
# @putenv "key" "val"
# Environment variables cannot be used in the options, however!
# Just call the compiler with several options:
cc = @if macosx or windows: llvm_gcc @else: gcc @end
lib="$nimrod/lib"
path="$lib/base"
path="$lib/base/gtk"
path="$lib/base/cairo"
path="$lib/base/x11"
path="$lib/base/sdl"
path="$lib/base/opengl"
path="$lib/windows"
path="$lib/posix"
path="$lib/ecmas"
path="$lib/extra"
@if release:
checks:off
stacktrace:off
debugger:off
line_dir:off
opt:speed
@end
# additional defines:
#define=""
# additional options always passed to the compiler:
line_dir=off
# use the new experimental symbol files for speeding up compilation:
#--symbol_files
--verbosity: "1"
hint[LineTooLong]=off
hint[XDeclaredButNotUsed]=off
@if unix:
@if not bsd: passl= "-ldl" @end
path = "$lib/base/gtk"
@end
@if icc:
passl = "-cxxlib"
passc = "-cxxlib"
@end
# Configuration for the LLVM GCC compiler:
@if windows:
llvm_gcc.path = r"$nimrod\dist\llvm-gcc4.2\bin"
@elif macosx:
llvm_gcc.path = r"/Users/andreasrumpf/download/C/llvm-gcc4.2-2.3-x86-darwin8/bin"
@end
llvm_gcc.options.debug = "-g"
llvm_gcc.options.always = "-w"
llvm_gcc.options.speed = "-O2 -fno-strict-aliasing -ffast-math"
llvm_gcc.options.size = "-Os -ffast-math"
# Configuration for the Borland C++ Compiler:
@if windows:
bcc.path = r"C:\eigenes\compiler\cbuilder5\bin"
@end
bcc.options.debug = ""
# turn off warnings about unreachable code and inline procs:
bcc.options.always = "-H- -q -RT- -a8 -w-8027 -w-8066 -w-8004"
bcc.options.speed = "-O2 -6"
bcc.options.size = "-O1 -6"
# Configuration for the Visual C/C++ compiler:
@if vcc:
@prepend_env path r"C:\Programme\Microsoft Visual Studio 9.0\Common7\IDE;"
@prepend_env INCLUDE r"C:\Programme\Microsoft Visual Studio 9.0\VC\include;C:\Programme\Microsoft Visual Studio 9.0\VC\ATLMFC\INCLUDE;C:\Programme\Microsoft SDKs\Windows\v6.0A\Include;"
@prepend_env LIB r"C:\Programme\Microsoft Visual Studio 9.0\VC\lib;C:\Programme\Microsoft Visual Studio 9.0\SDK\v2.0\Lib;C:\Programme\Microsoft SDKs\Windows\v6.0A\Lib;"
passl: r"/F33554432" # set the stack size to 8 MB
@end
@if windows:
vcc.path = r"C:\Programme\Microsoft Visual Studio 9.0\VC\bin"
@end
vcc.options.debug = "/RTC1 /ZI"
vcc.options.always = "/nologo"
vcc.options.speed = "/Ox /arch:SSE2"
vcc.options.size = "/O1"
# Configuration for the Watcom C/C++ compiler:
@if windows:
wcc.path = r"C:\eigenes\compiler\watcom\binnt"
@end
wcc.options.debug = "-d2"
wcc.options.always = "-6 -zw -w-"
wcc.options.speed = "-ox -on -6 -d0 -fp6 -zW"
wcc.options.size = "-ox -on -6 -d0 -fp6 -zW"
# Configuration for the GNU C/C++ compiler:
@if windows:
gcc.path = r"C:\eigenes\compiler\mingw\bin"
@end
gcc.options.debug = "-g"
@if macosx:
gcc.options.always = "-w -fasm-blocks"
@else:
gcc.options.always = "-w"
@end
gcc.options.speed = "-O3 -ffast-math"
gcc.options.size = "-Os -ffast-math"
# Configuration for the Digital Mars C/C++ compiler:
@if windows:
dmc.path = r"C:\eigenes\compiler\d\dm\bin"
@end
dmc.options.debug = "-g"
dmc.options.always = "-Jm"
dmc.options.speed = "-ff -o -6"
dmc.options.size = "-ff -o -6"
# Configuration for the LCC compiler:
@if windows:
lcc.path = r"C:\eigenes\compiler\lcc\bin"
@end
lcc.options.debug = "-g5"
lcc.options.always = "-e1"
lcc.options.speed = "-O -p6"
lcc.options.size = "-O -p6"
# Configuration for the Tiny C Compiler:
@if windows:
tcc.path = r"C:\Eigenes\compiler\tcc-0.9.23\tcc"
tcc.options.always = r"-IC:\Eigenes\compiler\tcc-0.9.23\include " &
r"-IC:\Eigenes\compiler\tcc-0.9.23\include\winapi"
@end
tcc.options.debug = ""
tcc.options.speed = ""
tcc.options.size = ""
# Configuration for the Pelles C compiler:
@if windows:
pcc.path = r"C:\eigenes\compiler\pellesc\bin"
@end
pcc.options.debug = "-Zi"
pcc.options.always = "-Ze"
pcc.options.speed = "-Ox"
pcc.options.size = "-Os"
@if windows:
icc.path = r"c:\eignes\compiler\icc\bin"
@end
icc.options.debug = "-g"
icc.options.always = "-w"
icc.options.speed = "-O3 -ffast-math"
icc.options.size = "-Os -ffast-math"
@write "used special config file"
@if ecmascript:
@write "Target is ECMAScript! No unsafe features are allowed!"
@end

View File

@@ -164,7 +164,7 @@ proc dbClose*(db: TDbConn) =
if db != nil: PQfinish(db)
proc dbOpen*(connection, user, password, database: string): TDbConn =
## opens a database connection. Returns nil in case of an error.
## opens a database connection.
result = PQsetdbLogin(nil, nil, nil, nil, database, user, password)
if PQStatus(result) != CONNECTION_OK: dbError(result) # result = nil

View File

@@ -16,7 +16,7 @@ from strutils import addf
type
TRegExDesc {.pure, final.} = object
re_nsub: int # Number of parenthesized subexpressions.
re_nsub: int # Number of parenthesized subexpressions.
value: pointer # For internal use only.
TRegEx* = ref TRegExDesc ## a compiled regular expression
@@ -122,9 +122,8 @@ proc rawmatch(s: string, pattern: TRegEx, matches: var openarray[string],
s.len-start, maxSubpatterns, addr(rawMatches), cint(0)))
if res == 0:
for i in 0..min(matches.len, int(pattern.re_nsub))-1:
var
a = int(rawMatches[i].so)
b = int(rawMatches[i].eo)
var a = int(rawMatches[i].so)
var b = int(rawMatches[i].eo)
echo "a: ", a, " b: ", b
if a >= 0 and b >= 0:
matches[i] = copy(s, a+start, b - 1 + start)
@@ -224,7 +223,7 @@ proc replace*(s: string, sub: TRegEx, by: string): string =
## with the notation ``$i`` and ``$#`` (see strutils.`%`). Examples:
##
## .. code-block:: nimrod
## "var1=key; var2=key2".replace(re"{\ident}'='{\ident}", "$1<-$2$2")
## "var1=key; var2=key2".replace(re"(\w+)'='(\w+)", "$1<-$2$2")
##
## Results in:
##
@@ -326,8 +325,10 @@ const ## common regular expressions
reOctal* = r"\b0[oO][0-7]+\b" ## describes an octal number (example: 0o777)
reFloat* = r"\b[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?\b"
## describes a floating point number
reEmail* = r"\b[a-zA-Z0-9!#$%&'*+/=?^_`{|}~\-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)" &
r"*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+(?:[a-zA-Z]{2}|com|org|" &
reEmail* = r"\b[a-zA-Z0-9!#$%&'*+/=?^_`{|}~\-]+(?:\. &" &
r"[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)" &
r"*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+" &
r"(?:[a-zA-Z]{2}|com|org|" &
r"net|gov|mil|biz|info|mobi|name|aero|jobs|museum)\b"
## describes a common email address
reURL* = r"\b(http(s)?|ftp|gopher|telnet|file|notes|ms\-help):" &

View File

@@ -1119,7 +1119,6 @@ when defined(USE_OLD_FUNCTIONS):
dynlib: External_library, importc: "mysql_create_db".}
proc mysql_drop_db*(mysql: PMYSQL, DB: cstring): cint{.stdcall,
dynlib: External_library, importc: "mysql_drop_db".}
proc mysql_reload*(mysql: PMySQL): cint
proc net_safe_read*(mysql: PMYSQL): cuint{.cdecl, dynlib: mysqllib,
importc: "net_safe_read".}

View File

@@ -1,35 +0,0 @@
//
//
// The Nimrod Compiler
// (c) Copyright 2009 Andreas Rumpf
//
// See the file "copying.txt", included in this
// distribution, for details about the copyright.
//
unit vis;
// Virtual instruction set for Nimrod. This is used for LLVM code generation.
interface
{$include 'config.inc'}
uses
nsystem, ast, astalgo, strutils, nhashes, trees, platform, magicsys,
extccomp, options, nversion, nimsets, msgs, crc, bitsets, idents,
lists, types, ccgutils, nos, ntime, ropes, nmath, passes, rodread,
wordrecg, rnimsyn, treetab;
type
TInstrKind = (
insAddi,
);
TInstruction = record
end;
implementation
end.

View File

@@ -305,7 +305,9 @@ type
mGCunref, mAddI, mSubI, mMulI, mDivI, mModI, mAddI64, mSubI64, mMulI64,
mDivI64, mModI64, mShrI, mShlI, mBitandI, mBitorI, mBitxorI, mMinI, mMaxI,
mShrI64, mShlI64, mBitandI64, mBitorI64, mBitxorI64, mMinI64, mMaxI64,
mAddF64, mSubF64, mMulF64, mDivF64, mMinF64, mMaxF64, mAddU, mSubU, mMulU,
mAddF64, mSubF64, mMulF64, mDivF64,
mMinF64, mMaxF64, mAddU, mSubU, mMulU,
mDivU, mModU, mAddU64, mSubU64, mMulU64, mDivU64, mModU64, mEqI, mLeI, mLtI,
mEqI64, mLeI64, mLtI64, mEqF64, mLeF64, mLtF64, mLeU, mLtU, mLeU64, mLtU64,
mEqEnum, mLeEnum, mLtEnum, mEqCh, mLeCh, mLtCh, mEqB, mLeB, mLtB, mEqRef,
@@ -505,44 +507,6 @@ type
const
OverloadableSyms* = {skProc, skMethod, skIterator, skConverter}
const
MagicToStr*: array[TMagic, string] = ["None", "Defined", "DefinedInScope",
"Low", "High", "SizeOf", "Is", "Echo", "Succ", "Pred", "Inc", "Dec", "Ord",
"New", "NewFinalize", "NewSeq", "LengthOpenArray", "LengthStr",
"LengthArray", "LengthSeq", "Incl", "Excl", "Card", "Chr", "GCref",
"GCunref", "AddI", "SubI", "MulI", "DivI", "ModI", "AddI64", "SubI64",
"MulI64", "DivI64", "ModI64", "ShrI", "ShlI", "BitandI", "BitorI",
"BitxorI", "MinI", "MaxI", "ShrI64", "ShlI64", "BitandI64", "BitorI64",
"BitxorI64", "MinI64", "MaxI64", "AddF64", "SubF64", "MulF64", "DivF64",
"MinF64", "MaxF64", "AddU", "SubU", "MulU", "DivU", "ModU", "AddU64",
"SubU64", "MulU64", "DivU64", "ModU64", "EqI", "LeI", "LtI", "EqI64",
"LeI64", "LtI64", "EqF64", "LeF64", "LtF64", "LeU", "LtU", "LeU64", "LtU64",
"EqEnum", "LeEnum", "LtEnum", "EqCh", "LeCh", "LtCh", "EqB", "LeB", "LtB",
"EqRef", "EqProc", "EqUntracedRef", "LePtr", "LtPtr", "EqCString", "Xor",
"UnaryMinusI", "UnaryMinusI64", "AbsI", "AbsI64", "Not", "UnaryPlusI",
"BitnotI", "UnaryPlusI64", "BitnotI64", "UnaryPlusF64", "UnaryMinusF64",
"AbsF64", "Ze8ToI", "Ze8ToI64", "Ze16ToI", "Ze16ToI64", "Ze32ToI64",
"ZeIToI64", "ToU8", "ToU16", "ToU32", "ToFloat", "ToBiggestFloat", "ToInt",
"ToBiggestInt", "CharToStr", "BoolToStr", "IntToStr", "Int64ToStr",
"FloatToStr", "CStrToStr", "StrToStr", "EnumToStr", "And", "Or", "EqStr",
"LeStr", "LtStr", "EqSet", "LeSet", "LtSet", "MulSet", "PlusSet",
"MinusSet", "SymDiffSet", "ConStrStr", "ConArrArr", "ConArrT", "ConTArr",
"ConTT", "Slice", "AppendStrCh", "AppendStrStr", "AppendSeqElem", "InRange",
"InSet", "Repr", "Exit", "SetLengthStr", "SetLengthSeq", "Assert", "Swap",
"IsNil", "ArrToSeq", "CopyStr", "CopyStrLast", "NewString", "Array",
"OpenArray", "Range", "Set", "Seq", "Ordinal", "Int", "Int8", "Int16",
"Int32", "Int64", "Float", "Float32", "Float64", "Bool", "Char", "String",
"Cstring", "Pointer", "EmptySet", "IntSetBaseType", "Nil", "Expr", "Stmt",
"TypeDesc", "IsMainModule", "CompileDate", "CompileTime", "NimrodVersion",
"NimrodMajor", "NimrodMinor", "NimrodPatch", "CpuEndian", "HostOS",
"HostCPU", "NaN", "Inf", "NegInf", "NLen", "NChild", "NSetChild", "NAdd",
"NAddMultiple", "NDel", "NKind", "NIntVal", "NFloatVal", "NSymbol",
"NIdent", "NGetType", "NStrVal", "NSetIntVal", "NSetFloatVal", "NSetSymbol",
"NSetIdent", "NSetType", "NSetStrVal", "NNewNimNode", "NCopyNimNode",
"NCopyNimTree", "StrToIdent", "IdentToStr", "EqIdent", "EqNimrodNode",
"NHint", "NWarning", "NError"]
const
GenericTypes*: TTypeKinds = {tyGenericInvokation, tyGenericBody,
tyGenericParam}
StructuralEquivTypes*: TTypeKinds = {tyArrayConstr, tyNil, tyTuple, tyArray,

View File

@@ -263,23 +263,23 @@ proc ropeConstr(indent: int, c: openarray[PRope]): PRope =
inc(i, 2)
appf(result, "$n$1}", [spaces(indent)])
proc symToYamlAux(n: PSym, marker: var TIntSet, indent: int, maxRecDepth: int): PRope =
var ast: PRope
proc symToYamlAux(n: PSym, marker: var TIntSet, indent: int,
maxRecDepth: int): PRope =
if n == nil:
result = toRope("null")
elif IntSetContainsOrIncl(marker, n.id):
result = ropef("\"$1 @$2\"", [toRope(n.name.s), toRope(
strutils.toHex(cast[TAddress](n), sizeof(n) * 2))])
else:
ast = treeToYamlAux(n.ast, marker, indent + 2, maxRecDepth - 1)
var ast = treeToYamlAux(n.ast, marker, indent + 2, maxRecDepth - 1)
result = ropeConstr(indent, [toRope("kind"),
makeYamlString($n.kind),
toRope("name"), makeYamlString(n.name.s),
toRope("typ"), typeToYamlAux(n.typ, marker,
indent + 2, maxRecDepth - 1), toRope("info"), lineInfoToStr(n.info),
indent + 2, maxRecDepth - 1),
toRope("info"), lineInfoToStr(n.info),
toRope("flags"), flagsToStr(n.flags),
toRope("magic"),
makeYamlString(MagicToStr[n.magic]),
toRope("magic"), makeYamlString($n.magic),
toRope("ast"), ast, toRope("options"),
flagsToStr(n.options), toRope("position"),
toRope(n.position)])

View File

@@ -573,44 +573,43 @@ proc genRecordFieldAux(p: BProc, e: PNode, d, a: var TLoc): PType =
result = getUniqueType(a.t)
proc genRecordField(p: BProc, e: PNode, d: var TLoc) =
var
a: TLoc
f, field: PSym
ty: PType
r: PRope
ty = genRecordFieldAux(p, e, d, a)
r = rdLoc(a)
f = e.sons[1].sym
field = nil
while ty != nil:
if not (ty.kind in {tyTuple, tyObject}):
InternalError(e.info, "genRecordField")
field = lookupInRecord(ty.n, f.name)
if field != nil: break
if gCmd != cmdCompileToCpp: app(r, ".Sup")
ty = GetUniqueType(ty.sons[0])
if field == nil: InternalError(e.info, "genRecordField")
if field.loc.r == nil: InternalError(e.info, "genRecordField")
appf(r, ".$1", [field.loc.r])
putIntoDest(p, d, field.typ, r)
var a: TLoc
var ty = genRecordFieldAux(p, e, d, a)
var r = rdLoc(a)
var f = e.sons[1].sym
if ty.n == nil:
# we found a unique tuple type which lacks field information
# so we use Field$i
appf(r, ".Field$1", [toRope(f.position)])
putIntoDest(p, d, f.typ, r)
else:
var field: PSym = nil
while ty != nil:
if not (ty.kind in {tyTuple, tyObject}):
InternalError(e.info, "genRecordField")
field = lookupInRecord(ty.n, f.name)
if field != nil: break
if gCmd != cmdCompileToCpp: app(r, ".Sup")
ty = GetUniqueType(ty.sons[0])
if field == nil: InternalError(e.info, "genRecordField")
if field.loc.r == nil: InternalError(e.info, "genRecordField")
appf(r, ".$1", [field.loc.r])
putIntoDest(p, d, field.typ, r)
proc genTupleElem(p: BProc, e: PNode, d: var TLoc) =
var
a: TLoc
field: PSym
ty: PType
r: PRope
i: int
initLocExpr(p, e.sons[0], a)
if d.k == locNone: d.s = a.s
discard getTypeDesc(p.module, a.t) # fill the record's fields.loc
ty = getUniqueType(a.t)
r = rdLoc(a)
var ty = getUniqueType(a.t)
var r = rdLoc(a)
case e.sons[1].kind
of nkIntLit..nkInt64Lit: i = int(e.sons[1].intVal)
else: internalError(e.info, "genTupleElem")
if ty.n != nil:
field = ty.n.sons[i].sym
var field = ty.n.sons[i].sym
if field == nil: InternalError(e.info, "genTupleElem")
if field.loc.r == nil: InternalError(e.info, "genTupleElem")
appf(r, ".$1", [field.loc.r])
@@ -1536,7 +1535,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
of mArrToSeq: genArrToSeq(p, e, d)
of mNLen..mNError:
liMessage(e.info, errCannotGenerateCodeForX, e.sons[0].sym.name.s)
else: internalError(e.info, "genMagicExpr: " & magicToStr[op])
else: internalError(e.info, "genMagicExpr: " & $op)
proc genConstExpr(p: BProc, n: PNode): PRope
proc handleConstExpr(p: BProc, n: PNode, d: var TLoc): bool =
@@ -1601,16 +1600,13 @@ proc genSetConstr(p: BProc, e: PNode, d: var TLoc) =
[rdLoc(d), rdSetElemLoc(a, e.typ)])
proc genTupleConstr(p: BProc, n: PNode, d: var TLoc) =
var
rec: TLoc
it: PNode
t: PType
var rec: TLoc
if not handleConstExpr(p, n, d):
t = getUniqueType(n.typ)
var t = getUniqueType(n.typ)
discard getTypeDesc(p.module, t) # so that any fields are initialized
if d.k == locNone: getTemp(p, t, d)
for i in countup(0, sonsLen(n) - 1):
it = n.sons[i]
var it = n.sons[i]
if it.kind == nkExprColonExpr:
initLoc(rec, locExpr, it.sons[1].typ, d.s)
if (t.n.sons[i].kind != nkSym): InternalError(n.info, "genTupleConstr")
@@ -1748,8 +1744,7 @@ proc expr(p: BProc, e: PNode, d: var TLoc) =
genMagicExpr(p, e, d, e.sons[0].sym.magic)
else:
genCall(p, e, d)
of nkCurly:
genSetConstr(p, e, d)
of nkCurly: genSetConstr(p, e, d)
of nkBracket:
if (skipTypes(e.typ, abstractVarRange).kind == tySequence):
genSeqConstr(p, e, d)

View File

@@ -66,12 +66,9 @@ proc getTypeName(typ: PType): PRope =
proc mapType(typ: PType): TCTypeKind =
case typ.kind
of tyNone:
result = ctVoid
of tyBool:
result = ctBool
of tyChar:
result = ctChar
of tyNone: result = ctVoid
of tyBool: result = ctBool
of tyChar: result = ctChar
of tySet:
case int(getSize(typ))
of 1: result = ctInt8
@@ -79,10 +76,8 @@ proc mapType(typ: PType): TCTypeKind =
of 4: result = ctInt32
of 8: result = ctInt64
else: result = ctArray
of tyOpenArray, tyArrayConstr, tyArray:
result = ctArray
of tyObject, tyTuple:
result = ctStruct
of tyOpenArray, tyArrayConstr, tyArray: result = ctArray
of tyObject, tyTuple: result = ctStruct
of tyGenericBody, tyGenericInst, tyGenericParam, tyDistinct, tyOrdinal:
result = mapType(lastSon(typ))
of tyEnum:
@@ -95,23 +90,17 @@ proc mapType(typ: PType): TCTypeKind =
of 4: result = ctInt32
of 8: result = ctInt64
else: internalError("mapType")
of tyRange:
result = mapType(typ.sons[0])
of tyRange: result = mapType(typ.sons[0])
of tyPtr, tyVar, tyRef:
case typ.sons[0].kind
of tyOpenArray, tyArrayConstr, tyArray: result = ctArray
else: result = ctPtr
of tyPointer:
result = ctPtr
of tySequence:
result = ctNimSeq
of tyProc:
result = ctProc
of tyString:
result = ctNimStr
of tyCString:
result = ctCString
of tyInt..tyFloat128:
of tyPointer: result = ctPtr
of tySequence: result = ctNimSeq
of tyProc: result = ctProc
of tyString: result = ctNimStr
of tyCString: result = ctCString
of tyInt..tyFloat128:
result = TCTypeKind(ord(typ.kind) - ord(tyInt) + ord(ctInt))
else: InternalError("mapType")
@@ -128,8 +117,7 @@ proc isInvalidReturnType(rettype: PType): bool =
# such a poor programming language.
# We exclude records with refs too. This enhances efficiency and
# is necessary for proper code generation of assignments.
if rettype == nil:
result = true
if rettype == nil: result = true
else:
case mapType(rettype)
of ctArray:
@@ -141,8 +129,9 @@ proc isInvalidReturnType(rettype: PType): bool =
const
CallingConvToStr: array[TCallingConvention, string] = ["N_NIMCALL",
"N_STDCALL", "N_CDECL", "N_SAFECALL", "N_SYSCALL", # this is probably not correct for all platforms,
# but one can #define it to what one wants so it will be no problem
"N_STDCALL", "N_CDECL", "N_SAFECALL",
"N_SYSCALL", # this is probably not correct for all platforms,
# but one can #define it to what one wants
"N_INLINE", "N_NOINLINE", "N_FASTCALL", "N_CLOSURE", "N_NOCONV"]
CallingConvToStrLLVM: array[TCallingConvention, string] = ["fastcc $1",
"stdcall $1", "ccc $1", "safecall $1", "syscall $1", "$1 alwaysinline",
@@ -163,8 +152,7 @@ proc getGlobalTempName(): PRope =
inc(gId)
proc ccgIntroducedPtr(s: PSym): bool =
var pt: PType
pt = s.typ
var pt = s.typ
assert(not (sfResult in s.flags))
case pt.Kind
of tyObject:
@@ -189,10 +177,6 @@ proc fillResult(param: PSym) =
proc genProcParams(m: BModule, t: PType, rettype, params: var PRope,
check: var TIntSet) =
var
j: int
param: PSym
arr: PType
params = nil
if (t.sons[0] == nil) or isInvalidReturnType(t.sons[0]):
rettype = toRope("void")
@@ -200,7 +184,7 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var PRope,
rettype = getTypeDescAux(m, t.sons[0], check)
for i in countup(1, sonsLen(t.n) - 1):
if t.n.sons[i].kind != nkSym: InternalError(t.n.info, "genProcParams")
param = t.n.sons[i].sym
var param = t.n.sons[i].sym
fillLoc(param.loc, locParam, param.typ, mangleName(param), OnStack)
app(params, getTypeDescAux(m, param.typ, check))
if ccgIntroducedPtr(param):
@@ -209,9 +193,9 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var PRope,
param.loc.s = OnUnknown
app(params, " ")
app(params, param.loc.r) # declare the len field for open arrays:
arr = param.typ
var arr = param.typ
if arr.kind == tyVar: arr = arr.sons[0]
j = 0
var j = 0
while arr.Kind == tyOpenArray:
# need to pass hidden parameter:
appff(params, ", NI $1Len$2", ", @NI $1Len$2", [param.loc.r, toRope(j)])
@@ -220,7 +204,7 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var PRope,
if i < sonsLen(t.n) - 1: app(params, ", ")
if (t.sons[0] != nil) and isInvalidReturnType(t.sons[0]):
if params != nil: app(params, ", ")
arr = t.sons[0]
var arr = t.sons[0]
app(params, getTypeDescAux(m, arr, check))
if (mapReturnType(t.sons[0]) != ctArray) or (gCmd == cmdCompileToLLVM):
app(params, "*")
@@ -266,23 +250,17 @@ proc getSimpleTypeDesc(m: BModule, typ: PType): PRope =
of tyString:
useMagic(m, "NimStringDesc")
result = typeNameOrLiteral(typ, "NimStringDesc*")
of tyCstring:
result = typeNameOrLiteral(typ, "NCSTRING")
of tyBool:
result = typeNameOrLiteral(typ, "NIM_BOOL")
of tyChar:
result = typeNameOrLiteral(typ, "NIM_CHAR")
of tyNil:
result = typeNameOrLiteral(typ, "0")
of tyCstring: result = typeNameOrLiteral(typ, "NCSTRING")
of tyBool: result = typeNameOrLiteral(typ, "NIM_BOOL")
of tyChar: result = typeNameOrLiteral(typ, "NIM_CHAR")
of tyNil: result = typeNameOrLiteral(typ, "0")
of tyInt..tyFloat128:
result = typeNameOrLiteral(typ, NumericalTypeToStr[typ.Kind])
of tyRange:
result = getSimpleTypeDesc(m, typ.sons[0])
of tyRange: result = getSimpleTypeDesc(m, typ.sons[0])
else: result = nil
proc getTypePre(m: BModule, typ: PType): PRope =
if typ == nil:
result = toRope("void")
if typ == nil: result = toRope("void")
else:
result = getSimpleTypeDesc(m, typ)
if result == nil: result = CacheGetType(m.typeCache, typ)

View File

@@ -34,21 +34,21 @@ type
cfsVars, # section for C variable declarations
cfsProcs, # section for C procs that are not inline
cfsTypeInit1, # section 1 for declarations of type information
cfsTypeInit2, # section 2 for initialization of type information
cfsTypeInit3, # section 3 for initialization of type information
cfsDebugInit, # section for initialization of debug information
cfsDynLibInit, # section for initialization of dynamic library binding
cfsTypeInit2, # section 2 for init of type information
cfsTypeInit3, # section 3 for init of type information
cfsDebugInit, # section for init of debug information
cfsDynLibInit, # section for init of dynamic library binding
cfsDynLibDeinit # section for deinitialization of dynamic libraries
TCTypeKind = enum # describes the type kind of a C type
ctVoid, ctChar, ctBool, ctUInt, ctUInt8, ctUInt16, ctUInt32, ctUInt64,
ctInt, ctInt8, ctInt16, ctInt32, ctInt64, ctFloat, ctFloat32, ctFloat64,
ctFloat128, ctArray, ctStruct, ctPtr, ctNimStr, ctNimSeq, ctProc, ctCString
TCFileSections = array[TCFileSection, PRope] # TCFileSections represents a generated C file
TCFileSections = array[TCFileSection, PRope] # represents a generated C file
TCProcSection = enum # the sections a generated C proc consists of
cpsLocals, # section of local variables for C proc
cpsInit, # section for initialization of variables for C proc
cpsStmts # section of local statements for C proc
TCProcSections = array[TCProcSection, PRope] # TCProcSections represents a generated C proc
TCProcSections = array[TCProcSection, PRope] # represents a generated C proc
BModule = ref TCGen
BProc = ref TCProc
TBlock{.final.} = object
@@ -99,7 +99,8 @@ var
gMapping: PRope # the generated mapping file (if requested)
gProcProfile: Natural # proc profile counter
gGeneratedSyms: TIntSet # set of ID's of generated symbols
gPendingModules: seq[BModule] = @ [] # list of modules that are not finished with code generation
gPendingModules: seq[BModule] = @[] # list of modules that are not
# finished with code generation
gForwardedProcsCounter: int = 0
gNimDat: BModule # generated global data
@@ -107,29 +108,27 @@ proc ropeff(cformat, llvmformat: string, args: openarray[PRope]): PRope =
if gCmd == cmdCompileToLLVM: result = ropef(llvmformat, args)
else: result = ropef(cformat, args)
proc appff(dest: var PRope, cformat, llvmformat: string, args: openarray[PRope]) =
proc appff(dest: var PRope, cformat, llvmformat: string,
args: openarray[PRope]) =
if gCmd == cmdCompileToLLVM: appf(dest, llvmformat, args)
else: appf(dest, cformat, args)
proc addForwardedProc(m: BModule, prc: PSym) =
var L: int
L = len(m.forwardedProcs)
var L = len(m.forwardedProcs)
setlen(m.forwardedProcs, L + 1)
m.forwardedProcs[L] = prc
inc(gForwardedProcsCounter)
proc addPendingModule(m: BModule) =
var L: int
for i in countup(0, high(gPendingModules)):
if gPendingModules[i] == m:
InternalError("module already pending: " & m.module.name.s)
L = len(gPendingModules)
var L = len(gPendingModules)
setlen(gPendingModules, L + 1)
gPendingModules[L] = m
proc findPendingModule(m: BModule, s: PSym): BModule =
var ms: PSym
ms = getModule(s)
var ms = getModule(s)
if ms.id == m.module.id:
return m
for i in countup(0, high(gPendingModules)):
@@ -776,8 +775,8 @@ proc rawNewModule(module: PSym, filename: string): BModule =
result.initProc = newProc(nil, result)
result.initProc.options = gOptions
initNodeTable(result.dataCache)
result.typeStack = @ []
result.forwardedProcs = @ []
result.typeStack = @[]
result.forwardedProcs = @[]
result.typeNodesName = getTempName()
result.nimTypesName = getTempName()
@@ -789,10 +788,8 @@ proc newModule(module: PSym, filename: string): BModule =
addPendingModule(result)
proc registerTypeInfoModule() =
const
moduleName = "nim__dat"
var s: PSym
s = NewSym(skModule, getIdent(moduleName), nil)
const moduleName = "nim__dat"
var s = NewSym(skModule, getIdent(moduleName), nil)
gNimDat = rawNewModule(s, joinPath(options.projectPath, moduleName) & ".nim")
addPendingModule(gNimDat)
appff(mainModProcs, "N_NOINLINE(void, $1)(void);$n",
@@ -805,41 +802,38 @@ proc myOpen(module: PSym, filename: string): PPassContext =
proc myOpenCached(module: PSym, filename: string, rd: PRodReader): PPassContext =
var cfile, cfilenoext, objFile: string
if gNimDat == nil:
registerTypeInfoModule() #MessageOut('cgen.myOpenCached has been called ' + filename);
registerTypeInfoModule()
#MessageOut('cgen.myOpenCached has been called ' + filename);
cfile = changeFileExt(completeCFilePath(filename), cExt)
cfilenoext = changeFileExt(cfile, "")
addFileToLink(cfilenoext)
registerModuleToMain(module) # XXX: this cannot be right here, initalization has to be appended during
# the ``myClose`` call
registerModuleToMain(module)
# XXX: this cannot be right here, initalization has to be appended during
# the ``myClose`` call
result = nil
proc shouldRecompile(code: PRope, cfile, cfilenoext: string): bool =
var objFile: string
result = true
if not (optForceFullMake in gGlobalOptions):
objFile = toObjFile(cfilenoext)
var objFile = toObjFile(cfilenoext)
if writeRopeIfNotEqual(code, cfile): return
if ExistsFile(objFile) and os.FileNewer(objFile, cfile): result = false
else:
writeRope(code, cfile)
proc myProcess(b: PPassContext, n: PNode): PNode =
var m: BModule
result = n
if b == nil: return
m = BModule(b)
var m = BModule(b)
m.initProc.options = gOptions
genStmts(m.initProc, n)
proc finishModule(m: BModule) =
var
i: int
prc: PSym
i = 0
var i = 0
while i <= high(m.forwardedProcs):
# Note: ``genProc`` may add to ``m.forwardedProcs``, so we cannot use
# a ``for`` loop here
prc = m.forwardedProcs[i]
var prc = m.forwardedProcs[i]
if sfForward in prc.flags: InternalError(prc.info, "still forwarded")
genProcNoForward(m, prc)
inc(i)
@@ -865,12 +859,9 @@ proc writeModule(m: BModule) =
addFileToLink(cfilenoext)
proc myClose(b: PPassContext, n: PNode): PNode =
var
m: BModule
disp: PNode
result = n
if b == nil: return
m = BModule(b)
var m = BModule(b)
if n != nil:
m.initProc.options = gOptions
genStmts(m.initProc, n)
@@ -879,11 +870,12 @@ proc myClose(b: PPassContext, n: PNode): PNode =
not (sfDeadCodeElim in m.module.flags):
finishModule(m)
if sfMainModule in m.module.flags:
disp = generateMethodDispatchers()
var disp = generateMethodDispatchers()
for i in countup(0, sonsLen(disp) - 1): genProcAux(gNimDat, disp.sons[i].sym)
genMainProc(m) # we need to process the transitive closure because recursive module
# deps are allowed (and the system module is processed in the wrong
# order anyway)
genMainProc(m)
# we need to process the transitive closure because recursive module
# deps are allowed (and the system module is processed in the wrong
# order anyway)
while gForwardedProcsCounter > 0:
for i in countup(0, high(gPendingModules)):
finishModule(gPendingModules[i])
@@ -902,4 +894,4 @@ proc cgenPass(): TPass =
result.close = myClose
InitIiTable(gToTypeInfoId)
IntSetInit(gGeneratedSyms)
IntSetInit(gGeneratedSyms)

View File

@@ -51,11 +51,10 @@ proc invalidPragma(n: PNode) =
liMessage(n.info, errInvalidPragmaX, renderTree(n, {renderNoComments}))
proc pragmaAsm(c: PContext, n: PNode): char =
var it: PNode
result = '\0'
if n != nil:
for i in countup(0, sonsLen(n) - 1):
it = n.sons[i]
var it = n.sons[i]
if (it.kind == nkExprColonExpr) and (it.sons[0].kind == nkIdent):
case whichKeyword(it.sons[0].ident)
of wSubsChar:
@@ -113,11 +112,12 @@ proc processMagic(c: PContext, n: PNode, s: PSym) =
if n.kind != nkExprColonExpr: liMessage(n.info, errStringLiteralExpected)
if n.sons[1].kind == nkIdent: v = n.sons[1].ident.s
else: v = expectStrLit(c, n)
incl(s.flags, sfImportc) # magics don't need an implementation, so we
# treat them as imported, instead of modifing a lot of working code
# BUGFIX: magic does not imply ``lfNoDecl`` anymore!
incl(s.flags, sfImportc)
# magics don't need an implementation, so we
# treat them as imported, instead of modifing a lot of working code
# BUGFIX: magic does not imply ``lfNoDecl`` anymore!
for m in countup(low(TMagic), high(TMagic)):
if magicToStr[m] == v:
if copy($m, 1) == v:
s.magic = m
return
liMessage(n.info, warnUnknownMagic, v)
@@ -146,9 +146,8 @@ proc pragmaDeadCodeElim(c: PContext, n: PNode) =
liMessage(n.info, errOnOrOffExpected)
proc processCallConv(c: PContext, n: PNode) =
var sw: TSpecialWord
if (n.kind == nkExprColonExpr) and (n.sons[1].kind == nkIdent):
sw = whichKeyword(n.sons[1].ident)
var sw = whichKeyword(n.sons[1].ident)
case sw
of firstCallConv..lastCallConv:
POptionEntry(c.optionStack.tail).defaultCC = wordToCallConv(sw)
@@ -157,8 +156,7 @@ proc processCallConv(c: PContext, n: PNode) =
liMessage(n.info, errCallConvExpected)
proc getLib(c: PContext, kind: TLibKind, path: string): PLib =
var it: PLib
it = PLib(c.libs.head)
var it = PLib(c.libs.head)
while it != nil:
if it.kind == kind:
if ospCaseInsensitive in platform.OS[targetOS].props:
@@ -173,32 +171,29 @@ proc getLib(c: PContext, kind: TLibKind, path: string): PLib =
Append(c.libs, result)
proc processDynLib(c: PContext, n: PNode, sym: PSym) =
var lib: PLib
if (sym == nil) or (sym.kind == skModule):
POptionEntry(c.optionStack.tail).dynlib = getLib(c, libDynamic,
expectStrLit(c, n))
elif n.kind == nkExprColonExpr:
lib = getLib(c, libDynamic, expectStrLit(c, n))
var lib = getLib(c, libDynamic, expectStrLit(c, n))
addToLib(lib, sym)
incl(sym.loc.flags, lfDynamicLib)
else:
incl(sym.loc.flags, lfExportLib)
proc processNote(c: PContext, n: PNode) =
var
x: int
nk: TNoteKind
if (n.kind == nkExprColonExpr) and (sonsLen(n) == 2) and
(n.sons[0].kind == nkBracketExpr) and
(n.sons[0].sons[1].kind == nkIdent) and
(n.sons[0].sons[0].kind == nkIdent) and (n.sons[1].kind == nkIdent):
var nk: TNoteKind
case whichKeyword(n.sons[0].sons[0].ident)
of wHint:
x = findStr(msgs.HintsToStr, n.sons[0].sons[1].ident.s)
var x = findStr(msgs.HintsToStr, n.sons[0].sons[1].ident.s)
if x >= 0: nk = TNoteKind(x + ord(hintMin))
else: invalidPragma(n)
of wWarning:
x = findStr(msgs.WarningsToStr, n.sons[0].sons[1].ident.s)
var x = findStr(msgs.WarningsToStr, n.sons[0].sons[1].ident.s)
if x >= 0: nk = TNoteKind(x + ord(warnMin))
else: InvalidPragma(n)
else:
@@ -212,53 +207,30 @@ proc processNote(c: PContext, n: PNode) =
invalidPragma(n)
proc processOption(c: PContext, n: PNode) =
var sw: TSpecialWord
if n.kind != nkExprColonExpr:
invalidPragma(n)
elif n.sons[0].kind == nkBracketExpr:
processNote(c, n)
elif n.sons[0].kind != nkIdent:
invalidPragma(n)
if n.kind != nkExprColonExpr: invalidPragma(n)
elif n.sons[0].kind == nkBracketExpr: processNote(c, n)
elif n.sons[0].kind != nkIdent: invalidPragma(n)
else:
sw = whichKeyword(n.sons[0].ident)
var sw = whichKeyword(n.sons[0].ident)
case sw
of wChecks:
OnOff(c, n, checksOptions)
of wObjChecks:
OnOff(c, n, {optObjCheck})
of wFieldchecks:
OnOff(c, n, {optFieldCheck})
of wRangechecks:
OnOff(c, n, {optRangeCheck})
of wBoundchecks:
OnOff(c, n, {optBoundsCheck})
of wOverflowchecks:
OnOff(c, n, {optOverflowCheck})
of wNilchecks:
OnOff(c, n, {optNilCheck})
of wAssertions:
OnOff(c, n, {optAssert})
of wWarnings:
OnOff(c, n, {optWarns})
of wHints:
OnOff(c, n, {optHints})
of wCallConv:
processCallConv(c, n) # ------ these are not in the Nimrod spec: -------------
of wLinedir:
OnOff(c, n, {optLineDir})
of wStacktrace:
OnOff(c, n, {optStackTrace})
of wLinetrace:
OnOff(c, n, {optLineTrace})
of wDebugger:
OnOff(c, n, {optEndb})
of wProfiler:
OnOff(c, n, {optProfiler})
of wByRef:
OnOff(c, n, {optByRef})
of wDynLib:
processDynLib(c, n, nil) #
# -------------------------------------------------------
of wChecks: OnOff(c, n, checksOptions)
of wObjChecks: OnOff(c, n, {optObjCheck})
of wFieldchecks: OnOff(c, n, {optFieldCheck})
of wRangechecks: OnOff(c, n, {optRangeCheck})
of wBoundchecks: OnOff(c, n, {optBoundsCheck})
of wOverflowchecks: OnOff(c, n, {optOverflowCheck})
of wNilchecks: OnOff(c, n, {optNilCheck})
of wAssertions: OnOff(c, n, {optAssert})
of wWarnings: OnOff(c, n, {optWarns})
of wHints: OnOff(c, n, {optHints})
of wCallConv: processCallConv(c, n)
of wLinedir: OnOff(c, n, {optLineDir})
of wStacktrace: OnOff(c, n, {optStackTrace})
of wLinetrace: OnOff(c, n, {optLineTrace})
of wDebugger: OnOff(c, n, {optEndb})
of wProfiler: OnOff(c, n, {optProfiler})
of wByRef: OnOff(c, n, {optByRef})
of wDynLib: processDynLib(c, n, nil)
of wOptimization:
if n.sons[1].kind != nkIdent:
invalidPragma(n)
@@ -277,22 +249,23 @@ proc processOption(c: PContext, n: PNode) =
else: liMessage(n.info, errOptionExpected)
proc processPush(c: PContext, n: PNode, start: int) =
var x, y: POptionEntry
x = newOptionEntry()
y = POptionEntry(c.optionStack.tail)
var x = newOptionEntry()
var y = POptionEntry(c.optionStack.tail)
x.options = gOptions
x.defaultCC = y.defaultCC
x.dynlib = y.dynlib
x.notes = gNotes
append(c.optionStack, x)
for i in countup(start, sonsLen(n) - 1):
processOption(c, n.sons[i]) #liMessage(n.info, warnUser, ropeToStr(optionsToStr(gOptions)));
processOption(c, n.sons[i])
#liMessage(n.info, warnUser, ropeToStr(optionsToStr(gOptions)));
proc processPop(c: PContext, n: PNode) =
if c.optionStack.counter <= 1:
liMessage(n.info, errAtPopWithoutPush)
else:
gOptions = POptionEntry(c.optionStack.tail).options #liMessage(n.info, warnUser, ropeToStr(optionsToStr(gOptions)));
gOptions = POptionEntry(c.optionStack.tail).options
#liMessage(n.info, warnUser, ropeToStr(optionsToStr(gOptions)));
gNotes = POptionEntry(c.optionStack.tail).notes
remove(c.optionStack, c.optionStack.tail)
@@ -315,11 +288,10 @@ type
linkNormal, linkSys
proc processCompile(c: PContext, n: PNode) =
var s, found, trunc: string
s = expectStrLit(c, n)
found = findFile(s)
var s = expectStrLit(c, n)
var found = findFile(s)
if found == "": found = s
trunc = ChangeFileExt(found, "")
var trunc = ChangeFileExt(found, "")
extccomp.addExternalFileToCompile(trunc)
extccomp.addFileToLink(completeCFilePath(trunc, false))
@@ -328,11 +300,9 @@ proc processCommonLink(c: PContext, n: PNode, feature: TLinkFeature) =
f = expectStrLit(c, n)
if splitFile(f).ext == "": f = toObjFile(f)
found = findFile(f)
if found == "":
found = f # use the default
if found == "": found = f # use the default
case feature
of linkNormal:
extccomp.addFileToLink(found)
of linkNormal: extccomp.addFileToLink(found)
of linkSys:
extccomp.addFileToLink(joinPath(libpath, completeCFilePath(found, false)))
else: internalError(n.info, "processCommonLink")
@@ -342,8 +312,7 @@ proc PragmaBreakpoint(c: PContext, n: PNode) =
proc PragmaCheckpoint(c: PContext, n: PNode) =
# checkpoints can be used to debug the compiler; they are not documented
var info: TLineInfo
info = n.info
var info = n.info
inc(info.line) # next line is affected!
msgs.addCheckpoint(info)
@@ -367,8 +336,7 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
of wExportc:
makeExternExport(sym, getOptionalStr(c, it, sym.name.s))
incl(sym.flags, sfUsed) # avoid wrong hints
of wImportc:
makeExternImport(sym, getOptionalStr(c, it, sym.name.s))
of wImportc: makeExternImport(sym, getOptionalStr(c, it, sym.name.s))
of wAlign:
if sym.typ == nil: invalidPragma(it)
sym.typ.align = expectIntLit(c, it)
@@ -389,10 +357,8 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
of wThreadVar:
noVal(it)
incl(sym.flags, sfThreadVar)
of wDeadCodeElim:
pragmaDeadCodeElim(c, it)
of wMagic:
processMagic(c, it, sym)
of wDeadCodeElim: pragmaDeadCodeElim(c, it)
of wMagic: processMagic(c, it, sym)
of wCompileTime:
noVal(it)
incl(sym.flags, sfCompileTime)
@@ -460,29 +426,19 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
of wFatal:
liMessage(it.info, errUser, expectStrLit(c, it))
quit(1)
of wDefine:
processDefine(c, it)
of wUndef:
processUndef(c, it)
of wCompile:
processCompile(c, it)
of wLink:
processCommonLink(c, it, linkNormal)
of wLinkSys:
processCommonLink(c, it, linkSys)
of wPassL:
extccomp.addLinkOption(expectStrLit(c, it))
of wPassC:
extccomp.addCompileOption(expectStrLit(c, it))
of wBreakpoint:
PragmaBreakpoint(c, it)
of wCheckpoint:
PragmaCheckpoint(c, it)
of wDefine: processDefine(c, it)
of wUndef: processUndef(c, it)
of wCompile: processCompile(c, it)
of wLink: processCommonLink(c, it, linkNormal)
of wLinkSys: processCommonLink(c, it, linkSys)
of wPassL: extccomp.addLinkOption(expectStrLit(c, it))
of wPassC: extccomp.addCompileOption(expectStrLit(c, it))
of wBreakpoint: PragmaBreakpoint(c, it)
of wCheckpoint: PragmaCheckpoint(c, it)
of wPush:
processPush(c, n, i + 1)
break
of wPop:
processPop(c, it)
of wPop: processPop(c, it)
of wChecks, wObjChecks, wFieldChecks, wRangechecks, wBoundchecks,
wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints,
wLinedir, wStacktrace, wLinetrace, wOptimization, wByRef, wCallConv,
@@ -493,10 +449,8 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
if sym.typ == nil: invalidPragma(it)
sym.typ.callConv = wordToCallConv(k)
else: invalidPragma(it)
else:
invalidPragma(it)
else:
processNote(c, it)
else: invalidPragma(it)
else: processNote(c, it)
if (sym != nil) and (sym.kind != skModule):
if (lfExportLib in sym.loc.flags) and not (sfExportc in sym.flags):
liMessage(n.info, errDynlibRequiresExportc)
@@ -506,4 +460,4 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
incl(sym.loc.flags, lfDynamicLib)
addToLib(lib, sym)
if sym.loc.r == nil: sym.loc.r = toRope(sym.name.s)

View File

@@ -275,7 +275,7 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode =
of mNewString, mExit, mInc, ast.mDec, mEcho, mAssert, mSwap, mAppendStrCh,
mAppendStrStr, mAppendSeqElem, mSetLengthStr, mSetLengthSeq, mNLen..mNError:
nil
else: InternalError(a.info, "evalOp(" & magicToStr[m] & ')')
else: InternalError(a.info, "evalOp(" & $m & ')')
proc getConstIfExpr(c: PSym, n: PNode): PNode =
var it, e: PNode

View File

@@ -63,6 +63,8 @@ Nimrod is efficient
Nimrod is expressive
====================
* **The Nimrod compiler and all of the standard library are implemented in
Nimrod.**
* Built-in high level datatypes: strings, sets, sequences, etc.
* Modern type system with local type inference, tuples, variants,
generics, etc.