beginning of a taint mode; type system enhancements
This commit is contained in:
parent
2359b8b107
commit
6023e994fb
18 changed files with 265 additions and 283 deletions
|
|
@ -143,6 +143,7 @@ type
|
|||
nkWhileStmt, # a while statement
|
||||
nkCaseStmt, # a case statement
|
||||
nkVarSection, # a var section
|
||||
nkLetSection, # a let section
|
||||
nkConstSection, # a const section
|
||||
nkConstDef, # a const definition
|
||||
nkTypeSection, # a type section (consists of type definitions)
|
||||
|
|
@ -178,6 +179,8 @@ type
|
|||
nkRefTy,
|
||||
nkPtrTy,
|
||||
nkVarTy,
|
||||
nkConstTy, # ``const T``
|
||||
nkMutableTy, # ``mutable T``
|
||||
nkDistinctTy, # distinct type
|
||||
nkProcTy,
|
||||
nkEnumTy,
|
||||
|
|
@ -186,7 +189,7 @@ type
|
|||
TNodeKinds* = set[TNodeKind]
|
||||
|
||||
type
|
||||
TSymFlag* = enum # already 29 flags!
|
||||
TSymFlag* = enum # already 30 flags!
|
||||
sfUsed, # read access of sym (for warnings) or simply used
|
||||
sfExported, # symbol is exported from module
|
||||
sfFromGeneric, # symbol is instantiation of a generic; this is needed
|
||||
|
|
@ -212,6 +215,7 @@ type
|
|||
sfProcvar, # proc can be passed to a proc var
|
||||
sfDiscriminant, # field is a discriminant in a record/object
|
||||
sfDeprecated, # symbol is deprecated
|
||||
sfError, # usage of symbol should trigger a compile-time error
|
||||
sfInClosure, # variable is accessed by a closure
|
||||
sfThread, # proc will run as a thread
|
||||
sfCompileTime, # proc can be evaluated at compile time
|
||||
|
|
@ -254,7 +258,12 @@ type
|
|||
tyPointer, tyOpenArray,
|
||||
tyString, tyCString, tyForward,
|
||||
tyInt, tyInt8, tyInt16, tyInt32, tyInt64, # signed integers
|
||||
tyFloat, tyFloat32, tyFloat64, tyFloat128
|
||||
tyFloat, tyFloat32, tyFloat64, tyFloat128,
|
||||
tyUInt, tyUInt8, tyUInt16, tyUInt32, tyUInt64,
|
||||
tyBigNum,
|
||||
tyConst, tyMutable, tyVarargs,
|
||||
tyIter, # unused
|
||||
tyProxy # currently unused
|
||||
|
||||
TTypeKinds* = set[TTypeKind]
|
||||
|
||||
|
|
|
|||
|
|
@ -30,94 +30,8 @@ const
|
|||
"Copyright (c) 2004-2011 by Andreas Rumpf\n"
|
||||
|
||||
const
|
||||
Usage = """
|
||||
Usage:
|
||||
nimrod command [options] [projectfile] [arguments]
|
||||
Command:
|
||||
compile, c compile project with default code generator (C)
|
||||
doc generate the documentation for inputfile
|
||||
i start Nimrod in interactive mode (limited)
|
||||
Arguments:
|
||||
arguments are passed to the program being run (if --run option is selected)
|
||||
Options:
|
||||
-p, --path:PATH add path to search paths
|
||||
-d, --define:SYMBOL define a conditional symbol
|
||||
-u, --undef:SYMBOL undefine a conditional symbol
|
||||
-f, --forceBuild force rebuilding of all modules
|
||||
--stackTrace:on|off turn stack tracing on|off
|
||||
--lineTrace:on|off turn line tracing on|off
|
||||
--threads:on|off turn support for multi-threading on|off
|
||||
-x, --checks:on|off turn all runtime checks on|off
|
||||
--objChecks:on|off turn obj conversion checks on|off
|
||||
--fieldChecks:on|off turn case variant field checks on|off
|
||||
--rangeChecks:on|off turn range checks on|off
|
||||
--boundChecks:on|off turn bound checks on|off
|
||||
--overflowChecks:on|off turn int over-/underflow checks on|off
|
||||
-a, --assertions:on|off turn assertions on|off
|
||||
--floatChecks:on|off turn all floating point (NaN/Inf) checks on|off
|
||||
--nanChecks:on|off turn NaN checks on|off
|
||||
--infChecks:on|off turn Inf checks on|off
|
||||
--deadCodeElim:on|off whole program dead code elimination on|off
|
||||
--opt:none|speed|size optimize not at all or for speed|size
|
||||
--app:console|gui|lib generate a console|GUI application|dynamic library
|
||||
-r, --run run the compiled program with given arguments
|
||||
--advanced show advanced command line switches
|
||||
-h, --help show this help
|
||||
"""
|
||||
|
||||
AdvancedUsage = """
|
||||
Advanced commands:
|
||||
compileToC, cc compile project with C code generator
|
||||
compileToCpp, cpp compile project to C++ code
|
||||
compileToOC, objc compile project to Objective C code
|
||||
rst2html convert a reStructuredText file to HTML
|
||||
rst2tex convert a reStructuredText file to TeX
|
||||
run run the project (with Tiny C backend; buggy!)
|
||||
pretty pretty print the inputfile
|
||||
genDepend generate a DOT file containing the
|
||||
module dependency graph
|
||||
dump dump all defined conditionals and search paths
|
||||
check checks the project for syntax and semantic
|
||||
idetools compiler support for IDEs: possible options:
|
||||
--track:FILE,LINE,COL track a file/cursor position
|
||||
--suggest suggest all possible symbols at position
|
||||
--def list all possible symbols at position
|
||||
--context list possible invokation context
|
||||
Advanced options:
|
||||
-o, --out:FILE set the output filename
|
||||
--stdout output to stdout
|
||||
-w, --warnings:on|off turn all warnings on|off
|
||||
--warning[X]:on|off turn specific warning X on|off
|
||||
--hints:on|off turn all hints on|off
|
||||
--hint[X]:on|off turn specific hint X on|off
|
||||
--lib:PATH set the system library path
|
||||
--nimcache:PATH set the path used for generated files
|
||||
-c, --compileOnly compile only; do not assemble or link
|
||||
--noLinking compile but do not link
|
||||
--noMain do not generate a main procedure
|
||||
--genScript generate a compile script (in the 'nimcache'
|
||||
subdirectory named 'compile_$project$scriptext')
|
||||
--os:SYMBOL set the target operating system (cross-compilation)
|
||||
--cpu:SYMBOL set the target processor (cross-compilation)
|
||||
--debuginfo enables debug information
|
||||
--debugger:on|off turn Embedded Nimrod Debugger on|off
|
||||
-t, --passc:OPTION pass an option to the C compiler
|
||||
-l, --passl:OPTION pass an option to the linker
|
||||
--genMapping generate a mapping file containing
|
||||
(Nimrod, mangled) identifier pairs
|
||||
--lineDir:on|off generation of #line directive on|off
|
||||
--threadanalysis:on|off turn thread analysis on|off
|
||||
--skipCfg do not read the general configuration file
|
||||
--skipProjCfg do not read the project's configuration file
|
||||
--gc:refc|boehm|none use Nimrod's native GC|Boehm GC|no GC
|
||||
--index:FILE use FILE to generate a documentation index file
|
||||
--putenv:key=value set an environment variable
|
||||
--listCmd list the commands used to execute external programs
|
||||
--parallelBuild=0|1|... perform a parallel build
|
||||
value = number of processors (0 for auto-detect)
|
||||
--verbosity:0|1|2|3 set Nimrod's verbosity level (0 is default)
|
||||
-v, --version show detailed version information
|
||||
"""
|
||||
Usage = slurp"doc/basicopt.txt".replace("//", "")
|
||||
AdvancedUsage = slurp"doc/advopt.txt".replace("//", "")
|
||||
|
||||
proc getCommandLineDesc(): string =
|
||||
result = `%`(HelpMessage, [VersionAsString, platform.os[platform.hostOS].name,
|
||||
|
|
@ -276,6 +190,7 @@ proc testCompileOption*(switch: string, info: TLineInfo): bool =
|
|||
of "symbolfiles": result = contains(gGlobalOptions, optSymbolFiles)
|
||||
of "genscript": result = contains(gGlobalOptions, optGenScript)
|
||||
of "threads": result = contains(gGlobalOptions, optThreads)
|
||||
of "taintmode": result = contains(gGlobalOptions, optTaintMode)
|
||||
else: InvalidCmdLineOption(passCmd1, switch, info)
|
||||
|
||||
proc processPath(path: string): string =
|
||||
|
|
@ -399,6 +314,7 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
|
|||
of "assertions", "a": ProcessOnOffSwitch({optAssert}, arg, pass, info)
|
||||
of "deadcodeelim": ProcessOnOffSwitchG({optDeadCodeElim}, arg, pass, info)
|
||||
of "threads": ProcessOnOffSwitchG({optThreads}, arg, pass, info)
|
||||
of "taintmode": ProcessOnOffSwitchG({optTaintMode}, arg, pass, info)
|
||||
of "opt":
|
||||
expectArg(switch, arg, pass, info)
|
||||
case arg.normalize
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ type
|
|||
errCannotInterpretNodeX, errFieldXNotFound, errInvalidConversionFromTypeX,
|
||||
errAssertionFailed, errCannotGenerateCodeForX, errXRequiresOneArgument,
|
||||
errUnhandledExceptionX, errCyclicTree, errXisNoMacroOrTemplate,
|
||||
errXhasSideEffects, errIteratorExpected,
|
||||
errXhasSideEffects, errIteratorExpected, errWrongSymbolX,
|
||||
errUser,
|
||||
warnCannotOpenFile,
|
||||
warnOctalEscape, warnXIsNeverRead, warnXmightNotBeenInit,
|
||||
|
|
@ -315,6 +315,7 @@ const
|
|||
errXisNoMacroOrTemplate: "\'$1\' is no macro or template",
|
||||
errXhasSideEffects: "\'$1\' can have side effects",
|
||||
errIteratorExpected: "iterator within for loop context expected",
|
||||
errWrongSymbolX: "usage of \'$1\' is a user-defined error",
|
||||
errUser: "$1",
|
||||
warnCannotOpenFile: "cannot open \'$1\' [CannotOpenFile]",
|
||||
warnOctalEscape: "octal escape sequences do not exist; leading zero is ignored [OctalEscape]",
|
||||
|
|
|
|||
|
|
@ -46,7 +46,8 @@ type # please make sure we have under 32 options
|
|||
optSuggest, # ideTools: 'suggest'
|
||||
optContext, # ideTools: 'context'
|
||||
optDef, # ideTools: 'def'
|
||||
optThreadAnalysis # thread analysis pass
|
||||
optThreadAnalysis, # thread analysis pass
|
||||
optTaintMode # taint mode turned on
|
||||
|
||||
TGlobalOptions* = set[TGlobalOption]
|
||||
TCommands* = enum # Nimrod's commands
|
||||
|
|
|
|||
|
|
@ -23,15 +23,15 @@ const
|
|||
wMagic, wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader,
|
||||
wCompilerProc, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge,
|
||||
wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC,
|
||||
wNoStackFrame}
|
||||
wNoStackFrame, wError}
|
||||
converterPragmas* = procPragmas
|
||||
methodPragmas* = procPragmas
|
||||
macroPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
|
||||
wMagic, wNosideEffect, wCompilerProc, wDeprecated, wExtern,
|
||||
wImportcpp, wImportobjc}
|
||||
wImportcpp, wImportobjc, wError}
|
||||
iteratorPragmas* = {FirstCallConv..LastCallConv, wNosideEffect, wSideEffect,
|
||||
wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern,
|
||||
wImportcpp, wImportobjc}
|
||||
wImportcpp, wImportobjc, wError}
|
||||
stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangechecks, wBoundchecks,
|
||||
wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints, wLinedir,
|
||||
wStacktrace, wLinetrace, wOptimization, wHint, wWarning, wError, wFatal,
|
||||
|
|
@ -43,14 +43,14 @@ const
|
|||
wDeprecated, wExtern, wThread, wImportcpp, wImportobjc, wNoStackFrame}
|
||||
typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl,
|
||||
wPure, wHeader, wCompilerProc, wFinal, wSize, wExtern, wShallow,
|
||||
wImportcpp, wImportobjc}
|
||||
wImportcpp, wImportobjc, wError}
|
||||
fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern,
|
||||
wImportcpp, wImportobjc}
|
||||
wImportcpp, wImportobjc, wError}
|
||||
varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl,
|
||||
wMagic, wHeader, wDeprecated, wCompilerProc, wDynLib, wExtern,
|
||||
wImportcpp, wImportobjc}
|
||||
wImportcpp, wImportobjc, wError}
|
||||
constPragmas* = {wImportc, wExportc, wHeader, wDeprecated, wMagic, wNodecl,
|
||||
wExtern, wImportcpp, wImportobjc}
|
||||
wExtern, wImportcpp, wImportobjc, wError}
|
||||
procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNosideEffect,
|
||||
wThread}
|
||||
allRoutinePragmas* = procPragmas + iteratorPragmas + lambdaPragmas
|
||||
|
|
@ -530,7 +530,12 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
|
|||
if sym.typ != nil: incl(sym.typ.flags, tfThread)
|
||||
of wHint: Message(it.info, hintUser, expectStrLit(c, it))
|
||||
of wWarning: Message(it.info, warnUser, expectStrLit(c, it))
|
||||
of wError: LocalError(it.info, errUser, expectStrLit(c, it))
|
||||
of wError:
|
||||
if sym != nil:
|
||||
noVal(it)
|
||||
incl(sym.flags, sfError)
|
||||
else:
|
||||
LocalError(it.info, errUser, expectStrLit(c, it))
|
||||
of wFatal: Fatal(it.info, errUser, expectStrLit(c, it))
|
||||
of wDefine: processDefine(c, it)
|
||||
of wUndef: processUndef(c, it)
|
||||
|
|
|
|||
|
|
@ -178,7 +178,9 @@ proc makeRangeType(c: PContext, first, last: biggestInt,
|
|||
|
||||
proc markUsed*(n: PNode, s: PSym) =
|
||||
incl(s.flags, sfUsed)
|
||||
if sfDeprecated in s.flags: Message(n.info, warnDeprecated, s.name.s)
|
||||
if {sfDeprecated, sfError} * s.flags != {}:
|
||||
if sfDeprecated in s.flags: Message(n.info, warnDeprecated, s.name.s)
|
||||
if sfError in s.flags: LocalError(n.info, errWrongSymbolX, s.name.s)
|
||||
|
||||
proc illFormedAst*(n: PNode) =
|
||||
GlobalError(n.info, errIllFormedAstX, renderTree(n, {renderNoComments}))
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ proc checkConversionBetweenObjects(info: TLineInfo, castDest, src: PType) =
|
|||
proc checkConvertible(info: TLineInfo, castDest, src: PType) =
|
||||
const
|
||||
IntegralTypes = {tyBool, tyEnum, tyChar, tyInt..tyFloat128}
|
||||
if sameType(castDest, src):
|
||||
if sameType(castDest, src) and castDest.sym == src.sym:
|
||||
# don't annoy conversions that may be needed on another processor:
|
||||
if not (castDest.kind in {tyInt..tyFloat128, tyNil}):
|
||||
Message(info, hintConvFromXtoItselfNotNeeded, typeToString(castDest))
|
||||
|
|
|
|||
|
|
@ -50,16 +50,19 @@ proc equalParams*(a, b: PNode): TParamsEquality
|
|||
proc isOrdinalType*(t: PType): bool
|
||||
proc enumHasHoles*(t: PType): bool
|
||||
const
|
||||
abstractPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyDistinct, tyOrdinal}
|
||||
abstractVar* = {tyVar, tyGenericInst, tyDistinct, tyOrdinal}
|
||||
abstractRange* = {tyGenericInst, tyRange, tyDistinct, tyOrdinal}
|
||||
abstractVarRange* = {tyGenericInst, tyRange, tyVar, tyDistinct, tyOrdinal}
|
||||
abstractInst* = {tyGenericInst, tyDistinct, tyOrdinal}
|
||||
abstractPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyDistinct, tyOrdinal,
|
||||
tyConst, tyMutable}
|
||||
abstractVar* = {tyVar, tyGenericInst, tyDistinct, tyOrdinal,
|
||||
tyConst, tyMutable}
|
||||
abstractRange* = {tyGenericInst, tyRange, tyDistinct, tyOrdinal,
|
||||
tyConst, tyMutable}
|
||||
abstractVarRange* = {tyGenericInst, tyRange, tyVar, tyDistinct, tyOrdinal,
|
||||
tyConst, tyMutable}
|
||||
abstractInst* = {tyGenericInst, tyDistinct, tyOrdinal, tyConst, tyMutable}
|
||||
|
||||
skipPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst}
|
||||
skipPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyConst, tyMutable}
|
||||
|
||||
proc skipTypes*(t: PType, kinds: TTypeKinds): PType
|
||||
proc elemType*(t: PType): PType
|
||||
proc containsObject*(t: PType): bool
|
||||
proc containsGarbageCollectedRef*(typ: PType): bool
|
||||
proc containsHiddenPointer*(typ: PType): bool
|
||||
|
|
@ -122,10 +125,11 @@ proc getOrdValue(n: PNode): biggestInt =
|
|||
result = 0
|
||||
|
||||
proc isCompatibleToCString(a: PType): bool =
|
||||
result = false
|
||||
if a.kind == tyArray:
|
||||
if (firstOrd(a.sons[0]) == 0) and
|
||||
(skipTypes(a.sons[0], {tyRange}).kind in {tyInt..tyInt64}) and
|
||||
(skipTypes(a.sons[0], {tyRange, tyConst,
|
||||
tyMutable, tyGenericInst}).kind in
|
||||
{tyInt..tyInt64, tyUInt..tyUInt64}) and
|
||||
(a.sons[1].kind == tyChar):
|
||||
result = true
|
||||
|
||||
|
|
@ -142,7 +146,7 @@ proc getProcHeader(sym: PSym): string =
|
|||
add(result, ')')
|
||||
if n.sons[0].typ != nil: result.add(": " & typeToString(n.sons[0].typ))
|
||||
|
||||
proc elemType(t: PType): PType =
|
||||
proc elemType*(t: PType): PType =
|
||||
assert(t != nil)
|
||||
case t.kind
|
||||
of tyGenericInst, tyDistinct: result = elemType(lastSon(t))
|
||||
|
|
@ -153,36 +157,7 @@ proc elemType(t: PType): PType =
|
|||
proc skipGeneric(t: PType): PType =
|
||||
result = t
|
||||
while result.kind == tyGenericInst: result = lastSon(result)
|
||||
|
||||
proc skipRange(t: PType): PType =
|
||||
result = t
|
||||
while result.kind == tyRange: result = base(result)
|
||||
|
||||
proc skipAbstract(t: PType): PType =
|
||||
result = t
|
||||
while result.kind in {tyRange, tyGenericInst}: result = lastSon(result)
|
||||
|
||||
proc skipVar(t: PType): PType =
|
||||
result = t
|
||||
while result.kind == tyVar: result = result.sons[0]
|
||||
|
||||
proc skipVarGeneric(t: PType): PType =
|
||||
result = t
|
||||
while result.kind in {tyGenericInst, tyVar}: result = lastSon(result)
|
||||
|
||||
proc skipPtrsGeneric(t: PType): PType =
|
||||
result = t
|
||||
while result.kind in {tyGenericInst, tyVar, tyPtr, tyRef}:
|
||||
result = lastSon(result)
|
||||
|
||||
proc skipVarGenericRange(t: PType): PType =
|
||||
result = t
|
||||
while result.kind in {tyGenericInst, tyVar, tyRange}: result = lastSon(result)
|
||||
|
||||
proc skipGenericRange(t: PType): PType =
|
||||
result = t
|
||||
while result.kind in {tyGenericInst, tyVar, tyRange}: result = lastSon(result)
|
||||
|
||||
|
||||
proc skipTypes(t: PType, kinds: TTypeKinds): PType =
|
||||
result = t
|
||||
while result.kind in kinds: result = lastSon(result)
|
||||
|
|
@ -190,18 +165,18 @@ proc skipTypes(t: PType, kinds: TTypeKinds): PType =
|
|||
proc isOrdinalType(t: PType): bool =
|
||||
assert(t != nil)
|
||||
result = (t.Kind in {tyChar, tyInt..tyInt64, tyBool, tyEnum}) or
|
||||
(t.Kind in {tyRange, tyOrdinal}) and isOrdinalType(t.sons[0])
|
||||
(t.Kind in {tyRange, tyOrdinal, tyConst, tyMutable, tyGenericInst}) and
|
||||
isOrdinalType(t.sons[0])
|
||||
|
||||
proc enumHasHoles(t: PType): bool =
|
||||
var b = t
|
||||
while b.kind == tyRange: b = b.sons[0]
|
||||
while b.kind in {tyConst, tyMutable, tyRange, tyGenericInst}: b = b.sons[0]
|
||||
result = b.Kind == tyEnum and tfEnumHasHoles in b.flags
|
||||
|
||||
proc iterOverTypeAux(marker: var TIntSet, t: PType, iter: TTypeIter,
|
||||
closure: PObject): bool
|
||||
proc iterOverNode(marker: var TIntSet, n: PNode, iter: TTypeIter,
|
||||
closure: PObject): bool =
|
||||
result = false
|
||||
if n != nil:
|
||||
case n.kind
|
||||
of nkNone..nkNilLit:
|
||||
|
|
@ -289,9 +264,9 @@ proc containsObject(t: PType): bool =
|
|||
result = searchTypeFor(t, isObjectPredicate)
|
||||
|
||||
proc isObjectWithTypeFieldPredicate(t: PType): bool =
|
||||
result = (t.kind == tyObject) and (t.sons[0] == nil) and
|
||||
not ((t.sym != nil) and (sfPure in t.sym.flags)) and
|
||||
not (tfFinal in t.flags)
|
||||
result = t.kind == tyObject and t.sons[0] == nil and
|
||||
not (t.sym != nil and sfPure in t.sym.flags) and
|
||||
tfFinal notin t.flags
|
||||
|
||||
proc analyseObjectWithTypeFieldAux(t: PType,
|
||||
marker: var TIntSet): TTypeFieldResult =
|
||||
|
|
@ -310,7 +285,7 @@ proc analyseObjectWithTypeFieldAux(t: PType,
|
|||
if res == frHeader: result = frHeader
|
||||
if result == frNone:
|
||||
if isObjectWithTypeFieldPredicate(t): result = frHeader
|
||||
of tyGenericInst, tyDistinct:
|
||||
of tyGenericInst, tyDistinct, tyConst, tyMutable:
|
||||
result = analyseObjectWithTypeFieldAux(lastSon(t), marker)
|
||||
of tyArray, tyArrayConstr, tyTuple:
|
||||
for i in countup(0, sonsLen(t) - 1):
|
||||
|
|
@ -406,8 +381,6 @@ proc mutateTypeAux(marker: var TIntSet, t: PType, iter: TTypeMutator,
|
|||
if not ContainsOrIncl(marker, t.id):
|
||||
for i in countup(0, sonsLen(t) - 1):
|
||||
result.sons[i] = mutateTypeAux(marker, result.sons[i], iter, closure)
|
||||
if (result.sons[i] == nil) and (result.kind == tyGenericInst):
|
||||
assert(false)
|
||||
if t.n != nil: result.n = mutateNode(marker, t.n, iter, closure)
|
||||
assert(result != nil)
|
||||
|
||||
|
|
@ -427,7 +400,10 @@ proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
|||
"distinct $1", "enum", "ordinal[$1]", "array[$1, $2]", "object", "tuple",
|
||||
"set[$1]", "range[$1]", "ptr ", "ref ", "var ", "seq[$1]", "proc",
|
||||
"pointer", "OpenArray[$1]", "string", "CString", "Forward", "int", "int8",
|
||||
"int16", "int32", "int64", "float", "float32", "float64", "float128"]
|
||||
"int16", "int32", "int64", "float", "float32", "float64", "float128",
|
||||
|
||||
"uint", "uint8", "uint16", "uint32", "uint64", "bignum", "const ",
|
||||
"!", "varargs[$1]", "iter[$1]", "proxy[$1]"]
|
||||
var t = typ
|
||||
result = ""
|
||||
if t == nil: return
|
||||
|
|
@ -474,7 +450,7 @@ proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
|||
add(result, typeToString(t.sons[i]))
|
||||
if i < sonsLen(t) - 1: add(result, ", ")
|
||||
add(result, ']')
|
||||
of tyPtr, tyRef, tyVar:
|
||||
of tyPtr, tyRef, tyVar, tyMutable, tyConst:
|
||||
result = typeToStr[t.kind] & typeToString(t.sons[0])
|
||||
of tyRange:
|
||||
result = "range " & rangeToStr(t.n)
|
||||
|
|
@ -495,6 +471,8 @@ proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
|||
addSep(prag)
|
||||
add(prag, "thread")
|
||||
if len(prag) != 0: add(result, "{." & prag & ".}")
|
||||
of tyVarargs, tyIter, tyProxy:
|
||||
result = typeToStr[t.kind] % typeToString(t.sons[0])
|
||||
else:
|
||||
result = typeToStr[t.kind]
|
||||
|
||||
|
|
@ -528,7 +506,8 @@ proc firstOrd(t: PType): biggestInt =
|
|||
else:
|
||||
assert(t.n.sons[0].kind == nkSym)
|
||||
result = t.n.sons[0].sym.position
|
||||
of tyGenericInst, tyDistinct: result = firstOrd(lastSon(t))
|
||||
of tyGenericInst, tyDistinct, tyConst, tyMutable:
|
||||
result = firstOrd(lastSon(t))
|
||||
else:
|
||||
InternalError("invalid kind for first(" & $t.kind & ')')
|
||||
result = 0
|
||||
|
|
@ -553,7 +532,8 @@ proc lastOrd(t: PType): biggestInt =
|
|||
of tyEnum:
|
||||
assert(t.n.sons[sonsLen(t.n) - 1].kind == nkSym)
|
||||
result = t.n.sons[sonsLen(t.n) - 1].sym.position
|
||||
of tyGenericInst, tyDistinct: result = lastOrd(lastSon(t))
|
||||
of tyGenericInst, tyDistinct, tyConst, tyMutable:
|
||||
result = lastOrd(lastSon(t))
|
||||
else:
|
||||
InternalError("invalid kind for last(" & $t.kind & ')')
|
||||
result = 0
|
||||
|
|
@ -561,21 +541,21 @@ proc lastOrd(t: PType): biggestInt =
|
|||
proc lengthOrd(t: PType): biggestInt =
|
||||
case t.kind
|
||||
of tyInt64, tyInt32, tyInt: result = lastOrd(t)
|
||||
of tyDistinct: result = lengthOrd(t.sons[0])
|
||||
of tyDistinct, tyConst, tyMutable: result = lengthOrd(t.sons[0])
|
||||
else: result = lastOrd(t) - firstOrd(t) + 1
|
||||
|
||||
proc equalParam(a, b: PSym): TParamsEquality =
|
||||
if SameTypeOrNil(a.typ, b.typ):
|
||||
if (a.ast == b.ast):
|
||||
if a.ast == b.ast:
|
||||
result = paramsEqual
|
||||
elif (a.ast != nil) and (b.ast != nil):
|
||||
elif a.ast != nil and b.ast != nil:
|
||||
if ExprStructuralEquivalent(a.ast, b.ast): result = paramsEqual
|
||||
else: result = paramsIncompatible
|
||||
elif (a.ast != nil):
|
||||
elif a.ast != nil:
|
||||
result = paramsEqual
|
||||
elif (b.ast != nil):
|
||||
elif b.ast != nil:
|
||||
result = paramsIncompatible
|
||||
else:
|
||||
else:
|
||||
result = paramsNotEqual
|
||||
|
||||
proc equalParams(a, b: PNode): TParamsEquality =
|
||||
|
|
@ -611,11 +591,10 @@ proc SameTypeOrNil(a, b: PType): bool =
|
|||
if a == b:
|
||||
result = true
|
||||
else:
|
||||
if (a == nil) or (b == nil): result = false
|
||||
if a == nil or b == nil: result = false
|
||||
else: result = SameType(a, b)
|
||||
|
||||
proc SameLiteral(x, y: PNode): bool =
|
||||
result = false
|
||||
if x.kind == y.kind:
|
||||
case x.kind
|
||||
of nkCharLit..nkInt64Lit: result = x.intVal == y.intVal
|
||||
|
|
@ -625,7 +604,7 @@ proc SameLiteral(x, y: PNode): bool =
|
|||
|
||||
proc SameRanges(a, b: PNode): bool =
|
||||
result = SameLiteral(a.sons[0], b.sons[0]) and
|
||||
SameLiteral(a.sons[1], b.sons[1])
|
||||
SameLiteral(a.sons[1], b.sons[1])
|
||||
|
||||
proc sameTuple(a, b: PType, DistinctOf: bool): bool =
|
||||
# two tuples are equivalent iff the names, types and positions are the same;
|
||||
|
|
@ -637,7 +616,7 @@ proc sameTuple(a, b: PType, DistinctOf: bool): bool =
|
|||
if DistinctOf: result = equalOrDistinctOf(a.sons[i], b.sons[i])
|
||||
else: result = SameType(a.sons[i], b.sons[i])
|
||||
if not result: return
|
||||
if (a.n != nil) and (b.n != nil):
|
||||
if a.n != nil and b.n != nil:
|
||||
for i in countup(0, sonsLen(a.n) - 1):
|
||||
# check field names:
|
||||
if a.n.sons[i].kind != nkSym: InternalError(a.n.info, "sameTuple")
|
||||
|
|
@ -659,13 +638,14 @@ proc SameType(x, y: PType): bool =
|
|||
return false
|
||||
case a.Kind
|
||||
of tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString,
|
||||
tyInt..tyFloat128, tyExpr, tyStmt, tyTypeDesc:
|
||||
tyInt..tyBigNum, tyExpr, tyStmt, tyTypeDesc:
|
||||
result = true
|
||||
of tyEnum, tyForward, tyObject, tyDistinct: result = (a.id == b.id)
|
||||
of tyEnum, tyForward, tyObject, tyDistinct, tyProxy: result = (a.id == b.id)
|
||||
of tyTuple: result = sameTuple(a, b, false)
|
||||
of tyGenericInst: result = sameType(lastSon(a), lastSon(b))
|
||||
of tyGenericParam, tyGenericInvokation, tyGenericBody, tySequence, tyOrdinal,
|
||||
tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr, tyArray, tyProc:
|
||||
tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr, tyArray, tyProc,
|
||||
tyConst, tyMutable, tyVarargs, tyIter:
|
||||
if sonsLen(a) == sonsLen(b):
|
||||
result = true
|
||||
for i in countup(0, sonsLen(a) - 1):
|
||||
|
|
@ -694,13 +674,14 @@ proc equalOrDistinctOf(x, y: PType): bool =
|
|||
return false
|
||||
case a.Kind
|
||||
of tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString,
|
||||
tyInt..tyFloat128, tyExpr, tyStmt, tyTypeDesc:
|
||||
tyInt..tyBigNum, tyExpr, tyStmt, tyTypeDesc:
|
||||
result = true
|
||||
of tyEnum, tyForward, tyObject, tyDistinct: result = (a.id == b.id)
|
||||
of tyEnum, tyForward, tyObject, tyDistinct, tyProxy: result = (a.id == b.id)
|
||||
of tyTuple: result = sameTuple(a, b, true)
|
||||
of tyGenericInst: result = equalOrDistinctOf(lastSon(a), lastSon(b))
|
||||
of tyGenericParam, tyGenericInvokation, tyGenericBody, tySequence, tyOrdinal,
|
||||
tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr, tyArray, tyProc:
|
||||
tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr, tyArray, tyProc,
|
||||
tyConst, tyMutable, tyVarargs, tyIter:
|
||||
if sonsLen(a) == sonsLen(b):
|
||||
result = true
|
||||
for i in countup(0, sonsLen(a) - 1):
|
||||
|
|
@ -769,7 +750,7 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool =
|
|||
result = false #InternalError('shit found');
|
||||
of tyEmpty, tyNil:
|
||||
result = kind == skConst
|
||||
of tyString, tyBool, tyChar, tyEnum, tyInt..tyFloat128, tyCString, tyPointer:
|
||||
of tyString, tyBool, tyChar, tyEnum, tyInt..tyBigNum, tyCString, tyPointer:
|
||||
result = true
|
||||
of tyOrdinal:
|
||||
result = kind == skParam
|
||||
|
|
@ -778,7 +759,7 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool =
|
|||
of tyRange:
|
||||
result = skipTypes(t.sons[0], abstractInst).kind in
|
||||
{tyChar, tyEnum, tyInt..tyFloat128}
|
||||
of tyOpenArray:
|
||||
of tyOpenArray, tyVarargs:
|
||||
result = (kind == skParam) and typeAllowedAux(marker, t.sons[0], skVar)
|
||||
of tySequence:
|
||||
result = (kind != skConst) and typeAllowedAux(marker, t.sons[0], skVar) or
|
||||
|
|
@ -788,7 +769,7 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool =
|
|||
t.sons[1].kind == tyEmpty
|
||||
of tyPtr, tyRef:
|
||||
result = typeAllowedAux(marker, t.sons[0], skVar)
|
||||
of tyArrayConstr, tyTuple, tySet:
|
||||
of tyArrayConstr, tyTuple, tySet, tyConst, tyMutable, tyIter, tyProxy:
|
||||
for i in countup(0, sonsLen(t) - 1):
|
||||
result = typeAllowedAux(marker, t.sons[i], kind)
|
||||
if not result: break
|
||||
|
|
@ -856,19 +837,19 @@ proc computeSizeAux(typ: PType, a: var biggestInt): biggestInt =
|
|||
return
|
||||
typ.size = - 2 # mark as being computed
|
||||
case typ.kind
|
||||
of tyInt:
|
||||
of tyInt, tyUInt:
|
||||
result = IntSize
|
||||
a = result
|
||||
of tyInt8, tyBool, tyChar:
|
||||
of tyInt8, tyUInt8, tyBool, tyChar:
|
||||
result = 1
|
||||
a = result
|
||||
of tyInt16:
|
||||
of tyInt16, tyUInt16:
|
||||
result = 2
|
||||
a = result
|
||||
of tyInt32, tyFloat32:
|
||||
of tyInt32, tyUInt32, tyFloat32:
|
||||
result = 4
|
||||
a = result
|
||||
of tyInt64, tyFloat64:
|
||||
of tyInt64, tyUInt64, tyFloat64:
|
||||
result = 8
|
||||
a = result
|
||||
of tyFloat:
|
||||
|
|
@ -878,7 +859,8 @@ proc computeSizeAux(typ: PType, a: var biggestInt): biggestInt =
|
|||
if typ.callConv == ccClosure: result = 2 * ptrSize
|
||||
else: result = ptrSize
|
||||
a = ptrSize
|
||||
of tyNil, tyCString, tyString, tySequence, tyPtr, tyRef, tyVar, tyOpenArray:
|
||||
of tyNil, tyCString, tyString, tySequence, tyPtr, tyRef, tyVar, tyOpenArray,
|
||||
tyBigNum:
|
||||
result = ptrSize
|
||||
a = result
|
||||
of tyArray, tyArrayConstr:
|
||||
|
|
@ -930,7 +912,8 @@ proc computeSizeAux(typ: PType, a: var biggestInt): biggestInt =
|
|||
if result < 0: return
|
||||
if a < maxAlign: a = maxAlign
|
||||
result = align(result, a)
|
||||
of tyGenericInst, tyDistinct, tyGenericBody:
|
||||
of tyGenericInst, tyDistinct, tyGenericBody, tyMutable, tyConst, tyIter,
|
||||
tyProxy:
|
||||
result = computeSizeAux(lastSon(typ), a)
|
||||
else:
|
||||
#internalError("computeSizeAux()")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue