mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-19 01:18:32 +00:00
bugfix: inconsequent tuple usage
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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):" &
|
||||
|
||||
@@ -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".}
|
||||
|
||||
35
nim/vis.pas
35
nim/vis.pas
@@ -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.
|
||||
42
rod/ast.nim
42
rod/ast.nim
@@ -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,
|
||||
|
||||
@@ -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)])
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
74
rod/cgen.nim
74
rod/cgen.nim
@@ -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)
|
||||
|
||||
170
rod/pragmas.nim
170
rod/pragmas.nim
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user