From a95316f78bf3a785c441c5832b5b11c262ef70ce Mon Sep 17 00:00:00 2001 From: cooldome Date: Thu, 26 Apr 2018 23:47:51 +0100 Subject: [PATCH 01/14] Implement float range types --- compiler/msgs.nim | 5 +- compiler/semtypes.nim | 4 +- compiler/sigmatch.nim | 33 +++++--- compiler/types.nim | 190 ++++++++++++++++++++++++++---------------- 4 files changed, 144 insertions(+), 88 deletions(-) diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 5ae2c4970..e16a5cea2 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -46,7 +46,8 @@ type errInvalidArgForX, errStmtHasNoEffect, errXExpectsTypeOrValue, errXExpectsArrayType, errIteratorCannotBeInstantiated, errExprXAmbiguous, errConstantDivisionByZero, errOrdinalTypeExpected, - errOrdinalOrFloatTypeExpected, errOverOrUnderflow, + errOrdinalOrFloatTypeExpected, errFloatTypeExpected, errStringTypeExpected, + errOverOrUnderflow, errCannotEvalXBecauseIncompletelyDefined, errChrExpectsRange0_255, errDynlibRequiresExportc, errUndeclaredFieldX, errNilAccess, errIndexOutOfBounds, errIndexTypesDoNotMatch, errBracketsInvalidForType, @@ -219,6 +220,8 @@ const errConstantDivisionByZero: "division by zero", errOrdinalTypeExpected: "ordinal type expected", errOrdinalOrFloatTypeExpected: "ordinal or float type expected", + errFloatTypeExpected: "float type expected", + errStringTypeExpected: "string type expected", errOverOrUnderflow: "over- or underflow", errCannotEvalXBecauseIncompletelyDefined: "cannot evaluate '$1' because type is not defined completely", errChrExpectsRange0_255: "\'chr\' expects an int in the range 0..255", diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 1fc263617..0d1688d33 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -205,8 +205,8 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType = if not hasUnknownTypes: if not sameType(rangeT[0].skipTypes({tyRange}), rangeT[1].skipTypes({tyRange})): localError(n.info, errPureTypeMismatch) - elif not rangeT[0].isOrdinalType: - localError(n.info, errOrdinalTypeExpected) + elif not rangeT[0].isOrdinalType and rangeT[0].kind notin tyFloat..tyFloat128: + localError(n.info, errOrdinalOrFloatTypeExpected) elif enumHasHoles(rangeT[0]): localError(n.info, errEnumXHasHoles, rangeT[0].sym.name.s) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 96d815df7..cb821c02f 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -628,20 +628,27 @@ proc procTypeRel(c: var TCandidate, f, a: PType): TTypeRelation = else: discard proc typeRangeRel(f, a: PType): TTypeRelation {.noinline.} = - let - a0 = firstOrd(a) - a1 = lastOrd(a) - f0 = firstOrd(f) - f1 = lastOrd(f) - if a0 == f0 and a1 == f1: - result = isEqual - elif a0 >= f0 and a1 <= f1: - result = isConvertible - elif a0 <= f1 and f0 <= a1: - # X..Y and C..D overlap iff (X <= D and C <= Y) - result = isConvertible + template check_range_in(t: typedesc): untyped = + let + a0 = firstValue[t](a) + a1 = lastValue[t](a) + f0 = firstValue[t](f) + f1 = lastValue[t](f) + if a0 == f0 and a1 == f1: + result = isEqual + elif a0 >= f0 and a1 <= f1: + result = isConvertible + elif a0 <= f1 and f0 <= a1: + # X..Y and C..D overlap iff (X <= D and C <= Y) + result = isConvertible + else: + result = isNone + + if f.isOrdinalType: + check_range_in(BiggestInt) else: - result = isNone + check_range_in(BiggestFloat) + proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType = var diff --git a/compiler/types.nim b/compiler/types.nim index 5d60fa9b4..19e61a332 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -86,14 +86,33 @@ proc isPureObject*(typ: PType): bool = t = t.sons[0].skipTypes(skipPtrs) result = t.sym != nil and sfPure in t.sym.flags -proc getOrdValue*(n: PNode): BiggestInt = +proc getValue*[T:BiggestInt|BiggestFloat|string](n: PNode): T = + ## get value of liternal node case n.kind - of nkCharLit..nkUInt64Lit: result = n.intVal - of nkNilLit: result = 0 - of nkHiddenStdConv: result = getOrdValue(n.sons[1]) + of nkNilLit: reset(result) + of nkHiddenStdConv: result = getValue[T](n.sons[1]) else: - localError(n.info, errOrdinalTypeExpected) - result = 0 + when T is BiggestInt: + case n.kind + of nkCharLit..nkUInt64Lit: result = n.intVal + else: + localError(n.info, errOrdinalTypeExpected) + result = 0 + elif T is BiggestFloat: + case n.kind + of nkFloatLiterals: result = n.floatVal + else: + localError(n.info, errFloatTypeExpected) + result = NaN + else: + case n.kind: + of nkStrLit..nkTripleStrLit: result = n.strVal + else: + localError(n.info, errStringTypeExpected) + result = nil + +proc getOrdValue*(n: PNode): BiggestInt {.inline.} = + getValue[BiggestInt](n) proc isIntLit*(t: PType): bool {.inline.} = result = t.kind == tyInt and t.n != nil and t.n.kind == nkIntLit @@ -587,79 +606,106 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = result = typeToStr[t.kind] result.addTypeFlags(t) -proc firstOrd*(t: PType): BiggestInt = - case t.kind - of tyBool, tyChar, tySequence, tyOpenArray, tyString, tyVarargs, tyProxy: - result = 0 - of tySet, tyVar: result = firstOrd(t.sons[0]) - of tyArray: result = firstOrd(t.sons[0]) - of tyRange: - assert(t.n != nil) # range directly given: - assert(t.n.kind == nkRange) - result = getOrdValue(t.n.sons[0]) - of tyInt: - if platform.intSize == 4: result = - (2147483646) - 2 - else: result = 0x8000000000000000'i64 - of tyInt8: result = - 128 - of tyInt16: result = - 32768 - of tyInt32: result = - 2147483646 - 2 - of tyInt64: result = 0x8000000000000000'i64 - of tyUInt..tyUInt64: result = 0 - of tyEnum: - # if basetype <> nil then return firstOrd of basetype - if sonsLen(t) > 0 and t.sons[0] != nil: - result = firstOrd(t.sons[0]) +proc firstValue*[T:BiggestInt|BiggestFloat](t: PType): T = + case t.kind: + of tyVar: result = firstValue[T](t.sons[0]) + of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias: + result = firstValue[T](lastSon(t)) + of tyRange: + assert(t.n != nil) # range directly given: + assert(t.n.kind == nkRange) + result = getValue[T](t.n.sons[0]) else: - assert(t.n.sons[0].kind == nkSym) - result = t.n.sons[0].sym.position - of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias: - result = firstOrd(lastSon(t)) - of tyOrdinal: - if t.len > 0: result = firstOrd(lastSon(t)) - else: internalError("invalid kind for first(" & $t.kind & ')') - else: - internalError("invalid kind for first(" & $t.kind & ')') - result = 0 + when T is BiggestInt: + case t.kind: + of tyBool, tyChar, tySequence, tyOpenArray, tyString, tyVarargs, tyProxy: + result = 0 + of tySet, tyVar: result = firstValue[T](t.sons[0]) + of tyArray: result = firstValue[T](t.sons[0]) + of tyInt: + if platform.intSize == 4: result = - (2147483646) - 2 + else: result = 0x8000000000000000'i64 + of tyInt8: result = - 128 + of tyInt16: result = - 32768 + of tyInt32: result = - 2147483646 - 2 + of tyInt64: result = 0x8000000000000000'i64 + of tyUInt..tyUInt64: result = 0 + of tyEnum: + # if basetype <> nil then return firstOrd of basetype + if sonsLen(t) > 0 and t.sons[0] != nil: + result = firstValue[T](t.sons[0]) + else: + assert(t.n.sons[0].kind == nkSym) + result = t.n.sons[0].sym.position + of tyOrdinal: + if t.len > 0: result = firstValue[T](lastSon(t)) + else: internalError("invalid kind for first(" & $t.kind & ')') + else: + internalError("invalid kind for first(" & $t.kind & ')') + result = 0 -proc lastOrd*(t: PType; fixedUnsigned = false): BiggestInt = + elif T is BiggestFloat: + case t.kind: + of tyFloat..tyFloat128: result = -Inf + else: + internalError("invalid kind for first(" & $t.kind & ')') + result = NaN + +proc firstOrd*(t: PType): BiggestInt {.inline.} = + firstValue[BiggestInt](t) + +proc lastValue*[T:BiggestInt|BiggestFloat](t: PType; fixedUnsigned = false): T = case t.kind - of tyBool: result = 1 - of tyChar: result = 255 - of tySet, tyVar: result = lastOrd(t.sons[0]) - of tyArray: result = lastOrd(t.sons[0]) + of tyVar: result = lastValue[T](t.sons[0]) + of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias: + result = lastValue[T](lastSon(t)) of tyRange: assert(t.n != nil) # range directly given: assert(t.n.kind == nkRange) - result = getOrdValue(t.n.sons[1]) - of tyInt: - if platform.intSize == 4: result = 0x7FFFFFFF - else: result = 0x7FFFFFFFFFFFFFFF'i64 - of tyInt8: result = 0x0000007F - of tyInt16: result = 0x00007FFF - of tyInt32: result = 0x7FFFFFFF - of tyInt64: result = 0x7FFFFFFFFFFFFFFF'i64 - of tyUInt: - if platform.intSize == 4: result = 0xFFFFFFFF - elif fixedUnsigned: result = 0xFFFFFFFFFFFFFFFF'i64 - else: result = 0x7FFFFFFFFFFFFFFF'i64 - of tyUInt8: result = 0xFF - of tyUInt16: result = 0xFFFF - of tyUInt32: result = 0xFFFFFFFF - of tyUInt64: - if fixedUnsigned: result = 0xFFFFFFFFFFFFFFFF'i64 - else: result = 0x7FFFFFFFFFFFFFFF'i64 - 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, tyTypeDesc, tyAlias: - result = lastOrd(lastSon(t)) - of tyProxy: result = 0 - of tyOrdinal: - if t.len > 0: result = lastOrd(lastSon(t)) - else: internalError("invalid kind for last(" & $t.kind & ')') + result = getValue[T](t.n.sons[1]) else: - internalError("invalid kind for last(" & $t.kind & ')') - result = 0 + when T is BiggestInt: + case t.kind + of tyBool: result = 1 + of tyChar: result = 255 + of tySet, tyArray: result = lastValue[T](t.sons[0]) + of tyInt: + if platform.intSize == 4: result = 0x7FFFFFFF + else: result = 0x7FFFFFFFFFFFFFFF'i64 + of tyInt8: result = 0x0000007F + of tyInt16: result = 0x00007FFF + of tyInt32: result = 0x7FFFFFFF + of tyInt64: result = 0x7FFFFFFFFFFFFFFF'i64 + of tyUInt: + if platform.intSize == 4: result = 0xFFFFFFFF + elif fixedUnsigned: result = 0xFFFFFFFFFFFFFFFF'i64 + else: result = 0x7FFFFFFFFFFFFFFF'i64 + of tyUInt8: result = 0xFF + of tyUInt16: result = 0xFFFF + of tyUInt32: result = 0xFFFFFFFF + of tyUInt64: + if fixedUnsigned: result = 0xFFFFFFFFFFFFFFFF'i64 + else: result = 0x7FFFFFFFFFFFFFFF'i64 + of tyEnum: + assert(t.n.sons[sonsLen(t.n) - 1].kind == nkSym) + result = t.n.sons[sonsLen(t.n) - 1].sym.position + + of tyProxy: result = 0 + of tyOrdinal: + if t.len > 0: result = lastValue[T](lastSon(t)) + else: internalError("invalid kind for last(" & $t.kind & ')') + else: + internalError("invalid kind for last(" & $t.kind & ')') + result = 0 + elif T is BiggestFloat: + case t.kind: + of tyFloat..tyFloat128: result = Inf + else: + internalError("invalid kind for first(" & $t.kind & ')') + result = NaN + +proc lastOrd*(t: PType; fixedUnsigned = false): BiggestInt {.inline.}= + lastValue[BiggestInt](t, fixedUnsigned) proc lengthOrd*(t: PType): BiggestInt = case t.kind From 0c9c1c013e9060ccafca9ac4c22031e687b6c984 Mon Sep 17 00:00:00 2001 From: cooldome Date: Sun, 29 Apr 2018 22:57:05 +0100 Subject: [PATCH 02/14] Add a test --- tests/float/tfloatrange.nim | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 tests/float/tfloatrange.nim diff --git a/tests/float/tfloatrange.nim b/tests/float/tfloatrange.nim new file mode 100644 index 000000000..56aaf7450 --- /dev/null +++ b/tests/float/tfloatrange.nim @@ -0,0 +1,37 @@ +discard """ + cmd: "nim c -d:release --rangeChecks:on $file" + output: '''StrictPositiveRange +float +range fail expected +''' +""" +import math, fenv + +type + Positive = range[0.0..Inf] + StrictPositive = range[minimumPositiveValue(float)..Inf] + Negative32 = range[-maximumPositiveValue(float32) .. -1.0'f32] + +proc myoverload(x: float) = + echo "float" + +proc myoverload(x: Positive) = + echo "PositiveRange" + +proc myoverload(x: StrictPositive) = + echo "StrictPositiveRange" + + +let x = 9.0.StrictPositive +myoverload(x) +myoverload(9.0) + +doAssert(sqrt(x) == 3.0) + +var z = -10.0 +try: + myoverload(StrictPositive(z)) +except: + echo "range fail expected" + + From b3a80dd2eb775367b52c1aed3f130cbdd51d36aa Mon Sep 17 00:00:00 2001 From: cooldome Date: Sun, 29 Apr 2018 23:17:07 +0100 Subject: [PATCH 03/14] update the doc --- changelog.md | 2 ++ compiler/types.nim | 2 +- doc/manual.rst | 10 +++++++--- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/changelog.md b/changelog.md index 8ac02a388..ddfeb4d36 100644 --- a/changelog.md +++ b/changelog.md @@ -81,6 +81,8 @@ Imported exceptions can be raised and caught just like Nim exceptions. More details in language manual. +- Range float typed, example `range[0.0 .. Inf]`. More details in language manual. + ### Tool changes - ``jsondoc2`` has been renamed ``jsondoc``, similar to how ``doc2`` was renamed diff --git a/compiler/types.nim b/compiler/types.nim index 19e61a332..bb6a132bb 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -704,7 +704,7 @@ proc lastValue*[T:BiggestInt|BiggestFloat](t: PType; fixedUnsigned = false): T = internalError("invalid kind for first(" & $t.kind & ')') result = NaN -proc lastOrd*(t: PType; fixedUnsigned = false): BiggestInt {.inline.}= +proc lastOrd*(t: PType; fixedUnsigned = false): BiggestInt {.inline.} = lastValue[BiggestInt](t, fixedUnsigned) proc lengthOrd*(t: PType): BiggestInt = diff --git a/doc/manual.rst b/doc/manual.rst index 636bf796b..e67d8c0f4 100644 --- a/doc/manual.rst +++ b/doc/manual.rst @@ -741,22 +741,26 @@ For further details, see `Convertible relation Subrange types -------------- -A subrange type is a range of values from an ordinal type (the base +A subrange type is a range of values from an ordinal or float point type (the base type). To define a subrange type, one must specify it's limiting values: the lowest and highest value of the type: .. code-block:: nim type Subrange = range[0..5] + PositiveFloat = range[0.0..Inf] ``Subrange`` is a subrange of an integer which can only hold the values 0 -to 5. Assigning any other value to a variable of type ``Subrange`` is a +to 5. ``PositiveFloat`` defines a subrange of all positive floating point values. +NaN does not belong to any subrange of floating point types. +Assigning any other value to a variable of type ``Subrange`` is a checked runtime error (or static error if it can be statically determined). Assignments from the base type to one of its subrange types (and vice versa) are allowed. -A subrange type has the same size as its base type (``int`` in the example). +A subrange type has the same size as its base type (``int`` in the +Subrange example). Pre-defined floating point types From 0ef93bdea4dba268e7e30e31aab7922ee55168f7 Mon Sep 17 00:00:00 2001 From: cooldome Date: Sun, 29 Apr 2018 23:26:21 +0100 Subject: [PATCH 04/14] update test --- tests/float/tfloatrange.nim | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/tests/float/tfloatrange.nim b/tests/float/tfloatrange.nim index 56aaf7450..e8ea1912e 100644 --- a/tests/float/tfloatrange.nim +++ b/tests/float/tfloatrange.nim @@ -3,6 +3,7 @@ discard """ output: '''StrictPositiveRange float range fail expected +range fail expected ''' """ import math, fenv @@ -21,7 +22,6 @@ proc myoverload(x: Positive) = proc myoverload(x: StrictPositive) = echo "StrictPositiveRange" - let x = 9.0.StrictPositive myoverload(x) myoverload(9.0) @@ -35,3 +35,15 @@ except: echo "range fail expected" +proc strictOnlyProc(x: StrictPositive): bool = + if x > 1.0: true else: false + +let x2 = 5.0.Positive +doAssert(strictOnlyProc(x2)) + +try: + let x4 = 0.0.Positive + discard strictOnlyProc(x4) +except: + echo "range fail expected" + \ No newline at end of file From 2d755a6f13059629badedb3e8130e07201acd519 Mon Sep 17 00:00:00 2001 From: cooldome Date: Mon, 30 Apr 2018 23:59:32 +0100 Subject: [PATCH 05/14] fix spacing in changelog --- changelog.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/changelog.md b/changelog.md index 936b7fb3f..543723252 100644 --- a/changelog.md +++ b/changelog.md @@ -87,8 +87,7 @@ is now invalid. Internally a Nim string still has the trailing zero for zero-copy interoperability with ``cstring``. Compile your code with the next switch ``--laxStrings:on`` if you need a transition period. - - + - Range float types, example `range[0.0 .. Inf]`. More details in language manual. ### Tool changes From f1185658cce0f74683d903ba8997f1d59e7dbaef Mon Sep 17 00:00:00 2001 From: cooldome Date: Sun, 10 Jun 2018 23:03:54 +0100 Subject: [PATCH 06/14] manual merge --- compiler/msgs.nim | 470 ---------------------------------------------- 1 file changed, 470 deletions(-) diff --git a/compiler/msgs.nim b/compiler/msgs.nim index d1e005464..533d3a57f 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -11,476 +11,6 @@ import options, strutils, os, tables, ropes, platform, terminal, macros, configuration -const - explanationsBaseUrl* = "https://nim-lang.org/docs/manual" - -type - TMsgKind* = enum - errUnknown, errInternal, errIllFormedAstX, errCannotOpenFile, errGenerated, - errStringLiteralExpected, - errIntLiteralExpected, errInvalidCharacterConstant, - errClosingTripleQuoteExpected, errClosingQuoteExpected, - errTabulatorsAreNotAllowed, errInvalidToken, - errInvalidNumber, errInvalidNumberOctalCode, errNumberOutOfRange, - errNnotAllowedInCharacter, errClosingBracketExpected, errMissingFinalQuote, - errIdentifierExpected, errNewlineExpected, errInvalidModuleName, - errOperatorExpected, errTokenExpected, - errRecursiveDependencyX, errOnOrOffExpected, errNoneSpeedOrSizeExpected, - errInvalidPragma, errUnknownPragma, errInvalidDirectiveX, - errAtPopWithoutPush, errEmptyAsm, errInvalidIndentation, - errExceptionAlreadyHandled, - errYieldNotAllowedHere, errYieldNotAllowedInTryStmt, - errInvalidNumberOfYieldExpr, errCannotReturnExpr, - errNoReturnWithReturnTypeNotAllowed, errAttemptToRedefine, - errStmtInvalidAfterReturn, errStmtExpected, errInvalidLabel, - errInvalidCmdLineOption, errCmdLineArgExpected, errCmdLineNoArgExpected, - errInvalidVarSubstitution, errUnknownVar, errUnknownCcompiler, - errOnOrOffExpectedButXFound, errOnOffOrListExpectedButXFound, - errNoneBoehmRefcExpectedButXFound, - errNoneSpeedOrSizeExpectedButXFound, errGuiConsoleOrLibExpectedButXFound, - errUnknownOS, errUnknownCPU, errGenOutExpectedButXFound, - errArgsNeedRunOption, errInvalidMultipleAsgn, errColonOrEqualsExpected, - errExprExpected, errUndeclaredField, - errUndeclaredRoutine, errUseQualifier, - errTypeExpected, - errSystemNeeds, errExecutionOfProgramFailed, errNotOverloadable, - errInvalidArgForX, errStmtHasNoEffect, errXExpectsTypeOrValue, - errXExpectsArrayType, errIteratorCannotBeInstantiated, errExprXAmbiguous, - errConstantDivisionByZero, errOrdinalTypeExpected, - errOrdinalOrFloatTypeExpected, errFloatTypeExpected, errStringTypeExpected, - errOverOrUnderflow, - errCannotEvalXBecauseIncompletelyDefined, errChrExpectsRange0_255, - errDynlibRequiresExportc, errUndeclaredFieldX, errNilAccess, - errIndexOutOfBounds, errIndexTypesDoNotMatch, errBracketsInvalidForType, - errValueOutOfSetBounds, errFieldInitTwice, errFieldNotInit, - errExprXCannotBeCalled, errExprHasNoType, errExprXHasNoType, - errCastNotInSafeMode, errExprCannotBeCastToX, errCommaOrParRiExpected, - errCurlyLeOrParLeExpected, errSectionExpected, errRangeExpected, - errMagicOnlyInSystem, errPowerOfTwoExpected, - errStringMayNotBeEmpty, errCallConvExpected, errProcOnlyOneCallConv, - errSymbolMustBeImported, errExprMustBeBool, errConstExprExpected, - errDuplicateCaseLabel, errRangeIsEmpty, errSelectorMustBeOfCertainTypes, - errSelectorMustBeOrdinal, errOrdXMustNotBeNegative, errLenXinvalid, - errWrongNumberOfVariables, errExprCannotBeRaised, errBreakOnlyInLoop, - errTypeXhasUnknownSize, errConstNeedsConstExpr, errConstNeedsValue, - errResultCannotBeOpenArray, errSizeTooBig, errSetTooBig, - errBaseTypeMustBeOrdinal, errInheritanceOnlyWithNonFinalObjects, - errInheritanceOnlyWithEnums, errIllegalRecursionInTypeX, - errCannotInstantiateX, errExprHasNoAddress, errXStackEscape, - errVarForOutParamNeededX, - errPureTypeMismatch, errTypeMismatch, errButExpected, errButExpectedX, - errAmbiguousCallXYZ, errWrongNumberOfArguments, - errWrongNumberOfArgumentsInCall, - errMissingGenericParamsForTemplate, - errXCannotBePassedToProcVar, - errPragmaOnlyInHeaderOfProcX, errImplOfXNotAllowed, - errImplOfXexpected, errNoSymbolToBorrowFromFound, errDiscardValueX, - errInvalidDiscard, errIllegalConvFromXtoY, errCannotBindXTwice, - errInvalidOrderInArrayConstructor, - errInvalidOrderInEnumX, errEnumXHasHoles, errExceptExpected, errInvalidTry, - errOptionExpected, errXisNoLabel, errNotAllCasesCovered, - errUnknownSubstitionVar, errComplexStmtRequiresInd, errXisNotCallable, - errNoPragmasAllowedForX, errNoGenericParamsAllowedForX, - errInvalidParamKindX, errDefaultArgumentInvalid, errNamedParamHasToBeIdent, - errNoReturnTypeForX, errConvNeedsOneArg, errInvalidPragmaX, - errXNotAllowedHere, errInvalidControlFlowX, - errXisNoType, errCircumNeedsPointer, errInvalidExpression, - errInvalidExpressionX, errEnumHasNoValueX, errNamedExprExpected, - errNamedExprNotAllowed, errXExpectsOneTypeParam, - errArrayExpectsTwoTypeParams, errInvalidVisibilityX, errInitHereNotAllowed, - errXCannotBeAssignedTo, errIteratorNotAllowed, errXNeedsReturnType, - errNoReturnTypeDeclared, - errNoCommand, errInvalidCommandX, errXOnlyAtModuleScope, - errXNeedsParamObjectType, - errTemplateInstantiationTooNested, errMacroInstantiationTooNested, - errInstantiationFrom, - errInvalidIndexValueForTuple, errCommandExpectsFilename, - errMainModuleMustBeSpecified, - errXExpected, - errTIsNotAConcreteType, - errCastToANonConcreteType, - errInvalidSectionStart, errGridTableNotImplemented, errGeneralParseError, - errNewSectionExpected, errWhitespaceExpected, errXisNoValidIndexFile, - errCannotRenderX, errVarVarTypeNotAllowed, errInstantiateXExplicitly, - errOnlyACallOpCanBeDelegator, errUsingNoSymbol, - errMacroBodyDependsOnGenericTypes, - errDestructorNotGenericEnough, - errInlineIteratorsAsProcParams, - errXExpectsTwoArguments, - errXExpectsObjectTypes, errXcanNeverBeOfThisSubtype, errTooManyIterations, - errCannotInterpretNodeX, errFieldXNotFound, errInvalidConversionFromTypeX, - errAssertionFailed, errCannotGenerateCodeForX, errXRequiresOneArgument, - errUnhandledExceptionX, errCyclicTree, errXisNoMacroOrTemplate, - errXhasSideEffects, errIteratorExpected, errLetNeedsInit, - errThreadvarCannotInit, errWrongSymbolX, errIllegalCaptureX, - errXCannotBeClosure, errXMustBeCompileTime, - errCannotInferTypeOfTheLiteral, - errCannotInferReturnType, - errCannotInferStaticParam, - errGenericLambdaNotAllowed, - errProcHasNoConcreteType, - errCompilerDoesntSupportTarget, - errInOutFlagNotExtern, - errUser, - warnCannotOpenFile, - warnOctalEscape, warnXIsNeverRead, warnXmightNotBeenInit, - warnDeprecated, warnConfigDeprecated, - warnSmallLshouldNotBeUsed, warnUnknownMagic, warnRedefinitionOfLabel, - warnUnknownSubstitutionX, warnLanguageXNotSupported, - warnFieldXNotSupported, warnCommentXIgnored, - warnNilStatement, warnTypelessParam, - warnUseBase, warnWriteToForeignHeap, warnUnsafeCode, - warnEachIdentIsTuple, warnShadowIdent, - warnProveInit, warnProveField, warnProveIndex, warnGcUnsafe, warnGcUnsafe2, - warnUninit, warnGcMem, warnDestructor, warnLockLevel, warnResultShadowed, - warnUser, - hintSuccess, hintSuccessX, - hintLineTooLong, hintXDeclaredButNotUsed, hintConvToBaseNotNeeded, - hintConvFromXtoItselfNotNeeded, hintExprAlwaysX, hintQuitCalled, - hintProcessing, hintCodeBegin, hintCodeEnd, hintConf, hintPath, - hintConditionAlwaysTrue, hintName, hintPattern, - hintExecuting, hintLinking, hintDependency, - hintSource, hintPerformance, hintStackTrace, hintGCStats, - hintUser, hintUserRaw - -const - MsgKindToStr*: array[TMsgKind, string] = [ - errUnknown: "unknown error", - errInternal: "internal error: $1", - errIllFormedAstX: "illformed AST: $1", - errCannotOpenFile: "cannot open \'$1\'", - errGenerated: "$1", - errStringLiteralExpected: "string literal expected", - errIntLiteralExpected: "integer literal expected", - errInvalidCharacterConstant: "invalid character constant", - errClosingTripleQuoteExpected: "closing \"\"\" expected, but end of file reached", - errClosingQuoteExpected: "closing \" expected", - errTabulatorsAreNotAllowed: "tabulators are not allowed", - errInvalidToken: "invalid token: $1", - errInvalidNumber: "$1 is not a valid number", - errInvalidNumberOctalCode: "$1 is not a valid number; did you mean octal? Then use one of '0o', '0c' or '0C'.", - errNumberOutOfRange: "number $1 out of valid range", - errNnotAllowedInCharacter: "\\n not allowed in character literal", - errClosingBracketExpected: "closing ']' expected, but end of file reached", - errMissingFinalQuote: "missing final \' for character literal", - errIdentifierExpected: "identifier expected, but found \'$1\'", - errNewlineExpected: "newline expected, but found \'$1\'", - errInvalidModuleName: "invalid module name: '$1'", - errOperatorExpected: "operator expected, but found \'$1\'", - errTokenExpected: "\'$1\' expected", - errRecursiveDependencyX: "recursive dependency: \'$1\'", - errOnOrOffExpected: "\'on\' or \'off\' expected", - errNoneSpeedOrSizeExpected: "\'none\', \'speed\' or \'size\' expected", - errInvalidPragma: "invalid pragma", - errUnknownPragma: "unknown pragma: \'$1\'", - errInvalidDirectiveX: "invalid directive: \'$1\'", - errAtPopWithoutPush: "\'pop\' without a \'push\' pragma", - errEmptyAsm: "empty asm statement", - errInvalidIndentation: "invalid indentation", - errExceptionAlreadyHandled: "exception already handled", - errYieldNotAllowedHere: "'yield' only allowed in an iterator", - errYieldNotAllowedInTryStmt: "'yield' cannot be used within 'try' in a non-inlined iterator", - errInvalidNumberOfYieldExpr: "invalid number of \'yield\' expressions", - errCannotReturnExpr: "current routine cannot return an expression", - errNoReturnWithReturnTypeNotAllowed: "routines with NoReturn pragma are not allowed to have return type", - errAttemptToRedefine: "redefinition of \'$1\'", - errStmtInvalidAfterReturn: "statement not allowed after \'return\', \'break\', \'raise\', \'continue\' or proc call with noreturn pragma", - errStmtExpected: "statement expected", - errInvalidLabel: "\'$1\' is no label", - errInvalidCmdLineOption: "invalid command line option: \'$1\'", - errCmdLineArgExpected: "argument for command line option expected: \'$1\'", - errCmdLineNoArgExpected: "invalid argument for command line option: \'$1\'", - errInvalidVarSubstitution: "invalid variable substitution in \'$1\'", - errUnknownVar: "unknown variable: \'$1\'", - errUnknownCcompiler: "unknown C compiler: \'$1\'", - errOnOrOffExpectedButXFound: "\'on\' or \'off\' expected, but \'$1\' found", - errOnOffOrListExpectedButXFound: "\'on\', \'off\' or \'list\' expected, but \'$1\' found", - errNoneBoehmRefcExpectedButXFound: "'none', 'boehm' or 'refc' expected, but '$1' found", - errNoneSpeedOrSizeExpectedButXFound: "'none', 'speed' or 'size' expected, but '$1' found", - errGuiConsoleOrLibExpectedButXFound: "'gui', 'console' or 'lib' expected, but '$1' found", - errUnknownOS: "unknown OS: '$1'", - errUnknownCPU: "unknown CPU: '$1'", - errGenOutExpectedButXFound: "'c', 'c++' or 'yaml' expected, but '$1' found", - errArgsNeedRunOption: "arguments can only be given if the '--run' option is selected", - errInvalidMultipleAsgn: "multiple assignment is not allowed", - errColonOrEqualsExpected: "\':\' or \'=\' expected, but found \'$1\'", - errExprExpected: "expression expected, but found \'$1\'", - errUndeclaredField: "undeclared field: \'$1\'", - errUndeclaredRoutine: "attempting to call undeclared routine: \'$1\'", - errUseQualifier: "ambiguous identifier: \'$1\' -- use a qualifier", - errTypeExpected: "type expected", - errSystemNeeds: "system module needs \'$1\'", - errExecutionOfProgramFailed: "execution of an external program failed: '$1'", - errNotOverloadable: "overloaded \'$1\' leads to ambiguous calls", - errInvalidArgForX: "invalid argument for \'$1\'", - errStmtHasNoEffect: "statement has no effect", - errXExpectsTypeOrValue: "\'$1\' expects a type or value", - errXExpectsArrayType: "\'$1\' expects an array type", - errIteratorCannotBeInstantiated: "'$1' cannot be instantiated because its body has not been compiled yet", - errExprXAmbiguous: "expression '$1' ambiguous in this context", - errConstantDivisionByZero: "division by zero", - errOrdinalTypeExpected: "ordinal type expected", - errOrdinalOrFloatTypeExpected: "ordinal or float type expected", - errFloatTypeExpected: "float type expected", - errStringTypeExpected: "string type expected", - errOverOrUnderflow: "over- or underflow", - errCannotEvalXBecauseIncompletelyDefined: "cannot evaluate '$1' because type is not defined completely", - errChrExpectsRange0_255: "\'chr\' expects an int in the range 0..255", - errDynlibRequiresExportc: "\'dynlib\' requires \'exportc\'", - errUndeclaredFieldX: "undeclared field: \'$1\'", - errNilAccess: "attempt to access a nil address", - errIndexOutOfBounds: "index out of bounds", - errIndexTypesDoNotMatch: "index types do not match", - errBracketsInvalidForType: "\'[]\' operator invalid for this type", - errValueOutOfSetBounds: "value out of set bounds", - errFieldInitTwice: "field initialized twice: \'$1\'", - errFieldNotInit: "field \'$1\' not initialized", - errExprXCannotBeCalled: "expression \'$1\' cannot be called", - errExprHasNoType: "expression has no type", - errExprXHasNoType: "expression \'$1\' has no type (or is ambiguous)", - errCastNotInSafeMode: "\'cast\' not allowed in safe mode", - errExprCannotBeCastToX: "expression cannot be cast to $1", - errCommaOrParRiExpected: "',' or ')' expected", - errCurlyLeOrParLeExpected: "\'{\' or \'(\' expected", - errSectionExpected: "section (\'type\', \'proc\', etc.) expected", - errRangeExpected: "range expected", - errMagicOnlyInSystem: "\'magic\' only allowed in system module", - errPowerOfTwoExpected: "power of two expected", - errStringMayNotBeEmpty: "string literal may not be empty", - errCallConvExpected: "calling convention expected", - errProcOnlyOneCallConv: "a proc can only have one calling convention", - errSymbolMustBeImported: "symbol must be imported if 'lib' pragma is used", - errExprMustBeBool: "expression must be of type 'bool'", - errConstExprExpected: "constant expression expected", - errDuplicateCaseLabel: "duplicate case label", - errRangeIsEmpty: "range is empty", - errSelectorMustBeOfCertainTypes: "selector must be of an ordinal type, float or string", - errSelectorMustBeOrdinal: "selector must be of an ordinal type", - errOrdXMustNotBeNegative: "ord($1) must not be negative", - errLenXinvalid: "len($1) must be less than 32768", - errWrongNumberOfVariables: "wrong number of variables", - errExprCannotBeRaised: "only a 'ref object' can be raised", - errBreakOnlyInLoop: "'break' only allowed in loop construct", - errTypeXhasUnknownSize: "type \'$1\' has unknown size", - errConstNeedsConstExpr: "a constant can only be initialized with a constant expression", - errConstNeedsValue: "a constant needs a value", - errResultCannotBeOpenArray: "the result type cannot be on open array", - errSizeTooBig: "computing the type\'s size produced an overflow", - errSetTooBig: "set is too large", - errBaseTypeMustBeOrdinal: "base type of a set must be an ordinal", - errInheritanceOnlyWithNonFinalObjects: "inheritance only works with non-final objects", - errInheritanceOnlyWithEnums: "inheritance only works with an enum", - errIllegalRecursionInTypeX: "illegal recursion in type \'$1\'", - errCannotInstantiateX: "cannot instantiate: \'$1\'", - errExprHasNoAddress: "expression has no address", - errXStackEscape: "address of '$1' may not escape its stack frame", - errVarForOutParamNeededX: "for a \'var\' type a variable needs to be passed; but '$1' is immutable", - errPureTypeMismatch: "type mismatch", - errTypeMismatch: "type mismatch: got <", - errButExpected: "but expected one of: ", - errButExpectedX: "but expected \'$1\'", - errAmbiguousCallXYZ: "ambiguous call; both $1 and $2 match for: $3", - errWrongNumberOfArguments: "wrong number of arguments", - errWrongNumberOfArgumentsInCall: "wrong number of arguments in call to '$1'", - errMissingGenericParamsForTemplate: "'$1' has unspecified generic parameters", - errXCannotBePassedToProcVar: "\'$1\' cannot be passed to a procvar", - errPragmaOnlyInHeaderOfProcX: "pragmas are only allowed in the header of a proc; redefinition of $1", - errImplOfXNotAllowed: "implementation of \'$1\' is not allowed", - errImplOfXexpected: "implementation of \'$1\' expected", - errNoSymbolToBorrowFromFound: "no symbol to borrow from found", - errDiscardValueX: "value of type '$1' has to be discarded", - errInvalidDiscard: "statement returns no value that can be discarded", - errIllegalConvFromXtoY: "conversion from $1 to $2 is invalid", - errCannotBindXTwice: "cannot bind parameter \'$1\' twice", - errInvalidOrderInArrayConstructor: "invalid order in array constructor", - errInvalidOrderInEnumX: "invalid order in enum \'$1\'", - errEnumXHasHoles: "enum \'$1\' has holes", - errExceptExpected: "\'except\' or \'finally\' expected", - errInvalidTry: "after catch all \'except\' or \'finally\' no section may follow", - errOptionExpected: "option expected, but found \'$1\'", - errXisNoLabel: "\'$1\' is not a label", - errNotAllCasesCovered: "not all cases are covered", - errUnknownSubstitionVar: "unknown substitution variable: \'$1\'", - errComplexStmtRequiresInd: "complex statement requires indentation", - errXisNotCallable: "\'$1\' is not callable", - errNoPragmasAllowedForX: "no pragmas allowed for $1", - errNoGenericParamsAllowedForX: "no generic parameters allowed for $1", - errInvalidParamKindX: "invalid param kind: \'$1\'", - errDefaultArgumentInvalid: "default argument invalid", - errNamedParamHasToBeIdent: "named parameter has to be an identifier", - errNoReturnTypeForX: "no return type allowed for $1", - errConvNeedsOneArg: "a type conversion needs exactly one argument", - errInvalidPragmaX: "invalid pragma: $1", - errXNotAllowedHere: "$1 not allowed here", - errInvalidControlFlowX: "invalid control flow: $1", - errXisNoType: "invalid type: \'$1\'", - errCircumNeedsPointer: "'[]' needs a pointer or reference type", - errInvalidExpression: "invalid expression", - errInvalidExpressionX: "invalid expression: \'$1\'", - errEnumHasNoValueX: "enum has no value \'$1\'", - errNamedExprExpected: "named expression expected", - errNamedExprNotAllowed: "named expression not allowed here", - errXExpectsOneTypeParam: "\'$1\' expects one type parameter", - errArrayExpectsTwoTypeParams: "array expects two type parameters", - errInvalidVisibilityX: "invalid visibility: \'$1\'", - errInitHereNotAllowed: "initialization not allowed here", - errXCannotBeAssignedTo: "\'$1\' cannot be assigned to", - errIteratorNotAllowed: "iterators can only be defined at the module\'s top level", - errXNeedsReturnType: "$1 needs a return type", - errNoReturnTypeDeclared: "no return type declared", - errNoCommand: "no command given", - errInvalidCommandX: "invalid command: \'$1\'", - errXOnlyAtModuleScope: "\'$1\' is only allowed at top level", - errXNeedsParamObjectType: "'$1' needs a parameter that has an object type", - errTemplateInstantiationTooNested: "template instantiation too nested, try --evalTemplateLimit:N", - errMacroInstantiationTooNested: "macro instantiation too nested, try --evalMacroLimit:N", - errInstantiationFrom: "template/generic instantiation from here", - errInvalidIndexValueForTuple: "invalid index value for tuple subscript", - errCommandExpectsFilename: "command expects a filename argument", - errMainModuleMustBeSpecified: "please, specify a main module in the project configuration file", - errXExpected: "\'$1\' expected", - errTIsNotAConcreteType: "\'$1\' is not a concrete type.", - errCastToANonConcreteType: "cannot cast to a non concrete type: \'$1\'", - errInvalidSectionStart: "invalid section start", - errGridTableNotImplemented: "grid table is not implemented", - errGeneralParseError: "general parse error", - errNewSectionExpected: "new section expected", - errWhitespaceExpected: "whitespace expected, got \'$1\'", - errXisNoValidIndexFile: "\'$1\' is no valid index file", - errCannotRenderX: "cannot render reStructuredText element \'$1\'", - errVarVarTypeNotAllowed: "type \'var var\' is not allowed", - errInstantiateXExplicitly: "instantiate '$1' explicitly", - errOnlyACallOpCanBeDelegator: "only a call operator can be a delegator", - errUsingNoSymbol: "'$1' is not a variable, constant or a proc name", - errMacroBodyDependsOnGenericTypes: "the macro body cannot be compiled, " & - "because the parameter '$1' has a generic type", - errDestructorNotGenericEnough: "Destructor signature is too specific. " & - "A destructor must be associated will all instantiations of a generic type", - errInlineIteratorsAsProcParams: "inline iterators can be used as parameters only for " & - "templates, macros and other inline iterators", - errXExpectsTwoArguments: "\'$1\' expects two arguments", - errXExpectsObjectTypes: "\'$1\' expects object types", - errXcanNeverBeOfThisSubtype: "\'$1\' can never be of this subtype", - errTooManyIterations: "interpretation requires too many iterations; " & - "if you are sure this is not a bug in your code edit " & - "compiler/vmdef.MaxLoopIterations and rebuild the compiler", - errCannotInterpretNodeX: "cannot evaluate \'$1\'", - errFieldXNotFound: "field \'$1\' cannot be found", - errInvalidConversionFromTypeX: "invalid conversion from type \'$1\'", - errAssertionFailed: "assertion failed", - errCannotGenerateCodeForX: "cannot generate code for \'$1\'", - errXRequiresOneArgument: "$1 requires one parameter", - errUnhandledExceptionX: "unhandled exception: $1", - errCyclicTree: "macro returned a cyclic abstract syntax tree", - errXisNoMacroOrTemplate: "\'$1\' is no macro or template", - errXhasSideEffects: "\'$1\' can have side effects", - errIteratorExpected: "iterator within for loop context expected", - errLetNeedsInit: "'let' symbol requires an initialization", - errThreadvarCannotInit: "a thread var cannot be initialized explicitly; this would only run for the main thread", - errWrongSymbolX: "usage of \'$1\' is a user-defined error", - errIllegalCaptureX: "illegal capture '$1'", - errXCannotBeClosure: "'$1' cannot have 'closure' calling convention", - errXMustBeCompileTime: "'$1' can only be used in compile-time context", - errCannotInferTypeOfTheLiteral: "cannot infer the type of the $1", - errCannotInferReturnType: "cannot infer the return type of the proc", - errCannotInferStaticParam: "cannot infer the value of the static param `$1`", - errGenericLambdaNotAllowed: "A nested proc can have generic parameters only when " & - "it is used as an operand to another routine and the types " & - "of the generic paramers can be inferred from the expected signature.", - errProcHasNoConcreteType: "'$1' doesn't have a concrete type, due to unspecified generic parameters.", - errCompilerDoesntSupportTarget: "The current compiler \'$1\' doesn't support the requested compilation target", - errInOutFlagNotExtern: "The `$1` modifier can be used only with imported types", - errUser: "$1", - warnCannotOpenFile: "cannot open \'$1\'", - warnOctalEscape: "octal escape sequences do not exist; leading zero is ignored", - warnXIsNeverRead: "\'$1\' is never read", - warnXmightNotBeenInit: "\'$1\' might not have been initialized", - warnDeprecated: "$1 is deprecated", - warnConfigDeprecated: "config file '$1' is deprecated", - warnSmallLshouldNotBeUsed: "\'l\' should not be used as an identifier; may look like \'1\' (one)", - warnUnknownMagic: "unknown magic \'$1\' might crash the compiler", - warnRedefinitionOfLabel: "redefinition of label \'$1\'", - warnUnknownSubstitutionX: "unknown substitution \'$1\'", - warnLanguageXNotSupported: "language \'$1\' not supported", - warnFieldXNotSupported: "field \'$1\' not supported", - warnCommentXIgnored: "comment \'$1\' ignored", - warnNilStatement: "'nil' statement is deprecated; use an empty 'discard' statement instead", - warnTypelessParam: "'$1' has no type. Typeless parameters are deprecated; only allowed for 'template'", - warnUseBase: "use {.base.} for base methods; baseless methods are deprecated", - warnWriteToForeignHeap: "write to foreign heap", - warnUnsafeCode: "unsafe code: '$1'", - warnEachIdentIsTuple: "each identifier is a tuple", - warnShadowIdent: "shadowed identifier: '$1'", - warnProveInit: "Cannot prove that '$1' is initialized. This will become a compile time error in the future.", - warnProveField: "cannot prove that field '$1' is accessible", - warnProveIndex: "cannot prove index '$1' is valid", - warnGcUnsafe: "not GC-safe: '$1'", - warnGcUnsafe2: "$1", - warnUninit: "'$1' might not have been initialized", - warnGcMem: "'$1' uses GC'ed memory", - warnDestructor: "usage of a type with a destructor in a non destructible context. This will become a compile time error in the future.", - warnLockLevel: "$1", - warnResultShadowed: "Special variable 'result' is shadowed.", - warnUser: "$1", - hintSuccess: "operation successful", - hintSuccessX: "operation successful ($# lines compiled; $# sec total; $#; $#)", - hintLineTooLong: "line too long", - hintXDeclaredButNotUsed: "\'$1\' is declared but not used", - hintConvToBaseNotNeeded: "conversion to base object is not needed", - hintConvFromXtoItselfNotNeeded: "conversion from $1 to itself is pointless", - hintExprAlwaysX: "expression evaluates always to \'$1\'", - hintQuitCalled: "quit() called", - hintProcessing: "$1", - hintCodeBegin: "generated code listing:", - hintCodeEnd: "end of listing", - hintConf: "used config file \'$1\'", - hintPath: "added path: '$1'", - hintConditionAlwaysTrue: "condition is always true: '$1'", - hintName: "name should be: '$1'", - hintPattern: "$1", - hintExecuting: "$1", - hintLinking: "", - hintDependency: "$1", - hintSource: "$1", - hintPerformance: "$1", - hintStackTrace: "$1", - hintGCStats: "$1", - hintUser: "$1", - hintUserRaw: "$1"] - -const - WarningsToStr* = ["CannotOpenFile", "OctalEscape", - "XIsNeverRead", "XmightNotBeenInit", - "Deprecated", "ConfigDeprecated", - "SmallLshouldNotBeUsed", "UnknownMagic", - "RedefinitionOfLabel", "UnknownSubstitutionX", - "LanguageXNotSupported", "FieldXNotSupported", - "CommentXIgnored", "NilStmt", - "TypelessParam", "UseBase", "WriteToForeignHeap", - "UnsafeCode", "EachIdentIsTuple", "ShadowIdent", - "ProveInit", "ProveField", "ProveIndex", "GcUnsafe", "GcUnsafe2", "Uninit", - "GcMem", "Destructor", "LockLevel", "ResultShadowed", "User"] - - HintsToStr* = ["Success", "SuccessX", "LineTooLong", - "XDeclaredButNotUsed", "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded", - "ExprAlwaysX", "QuitCalled", "Processing", "CodeBegin", "CodeEnd", "Conf", - "Path", "CondTrue", "Name", "Pattern", "Exec", "Link", "Dependency", - "Source", "Performance", "StackTrace", "GCStats", - "User", "UserRaw"] - -const - fatalMin* = errUnknown - fatalMax* = errInternal - errMin* = errUnknown - errMax* = errUser - warnMin* = warnCannotOpenFile - warnMax* = pred(hintSuccess) - hintMin* = hintSuccess - hintMax* = high(TMsgKind) - -static: - doAssert HintsToStr.len == ord(hintMax) - ord(hintMin) + 1 - doAssert WarningsToStr.len == ord(warnMax) - ord(warnMin) + 1 #type # MsgConfig* = ref object of RootObj From 17ab7aff449865937c7901dc0314e5990b032c01 Mon Sep 17 00:00:00 2001 From: cooldome Date: Sun, 10 Jun 2018 23:05:50 +0100 Subject: [PATCH 07/14] manual merge continues --- compiler/types.nim | 46 ++++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/compiler/types.nim b/compiler/types.nim index 30c52e127..1fab842cc 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -86,11 +86,11 @@ proc isPureObject*(typ: PType): bool = t = t.sons[0].skipTypes(skipPtrs) result = t.sym != nil and sfPure in t.sym.flags -proc getValue*[T:BiggestInt|BiggestFloat|string](n: PNode): T = - ## get value of liternal node +proc getOrdValue*(n: PNode): BiggestInt = case n.kind - of nkNilLit: reset(result) - of nkHiddenStdConv: result = getValue[T](n.sons[1]) + of nkCharLit..nkUInt64Lit: result = n.intVal + of nkNilLit: result = 0 + of nkHiddenStdConv: result = getOrdValue(n.sons[1]) else: #localError(n.info, errOrdinalTypeExpected) # XXX check usages of getOrdValue @@ -589,15 +589,28 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = result = typeToStr[t.kind] result.addTypeFlags(t) -proc firstValue*[T:BiggestInt|BiggestFloat](t: PType): T = - case t.kind: - of tyVar: result = firstValue[T](t.sons[0]) - of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias: - result = firstValue[T](lastSon(t)) - of tyRange: - assert(t.n != nil) # range directly given: - assert(t.n.kind == nkRange) - result = getValue[T](t.n.sons[0]) +proc firstOrd*(t: PType): BiggestInt = + case t.kind + of tyBool, tyChar, tySequence, tyOpenArray, tyString, tyVarargs, tyProxy: + result = 0 + of tySet, tyVar: result = firstOrd(t.sons[0]) + of tyArray: result = firstOrd(t.sons[0]) + of tyRange: + assert(t.n != nil) # range directly given: + assert(t.n.kind == nkRange) + result = getOrdValue(t.n.sons[0]) + of tyInt: + if platform.intSize == 4: result = - (2147483646) - 2 + else: result = 0x8000000000000000'i64 + of tyInt8: result = - 128 + of tyInt16: result = - 32768 + of tyInt32: result = - 2147483646 - 2 + of tyInt64: result = 0x8000000000000000'i64 + of tyUInt..tyUInt64: result = 0 + of tyEnum: + # if basetype <> nil then return firstOrd of basetype + if sonsLen(t) > 0 and t.sons[0] != nil: + result = firstOrd(t.sons[0]) else: assert(t.n.sons[0].kind == nkSym) result = t.n.sons[0].sym.position @@ -612,9 +625,10 @@ proc firstValue*[T:BiggestInt|BiggestFloat](t: PType): T = proc lastOrd*(t: PType; fixedUnsigned = false): BiggestInt = case t.kind - of tyVar: result = lastValue[T](t.sons[0]) - of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias: - result = lastValue[T](lastSon(t)) + of tyBool: result = 1 + of tyChar: result = 255 + of tySet, tyVar: result = lastOrd(t.sons[0]) + of tyArray: result = lastOrd(t.sons[0]) of tyRange: assert(t.n != nil) # range directly given: assert(t.n.kind == nkRange) From 4d87d666ee12d9a16a0a3b21ab30b46f9e933cb0 Mon Sep 17 00:00:00 2001 From: cooldome Date: Sun, 10 Jun 2018 23:07:05 +0100 Subject: [PATCH 08/14] manual merge --- compiler/semtypes.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 366ba9cb7..602c5eeaf 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -232,9 +232,9 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType = if not hasUnknownTypes: if not sameType(rangeT[0].skipTypes({tyRange}), rangeT[1].skipTypes({tyRange})): - localError(c.config, n.info, errPureTypeMismatch) + localError(c.config, n.info, "type mismatch") elif not rangeT[0].isOrdinalType and rangeT[0].kind notin tyFloat..tyFloat128: - localError(c.config, n.info, errOrdinalOrFloatTypeExpected) + localError(c.config, n.info, "ordinal or float type expected") elif enumHasHoles(rangeT[0]): localError(c.config, n.info, "enum '$1' has holes" % typeToString(rangeT[0])) From a65e9c0e2520911d16b81e7af47fea8c3fdd2958 Mon Sep 17 00:00:00 2001 From: cooldome Date: Sun, 10 Jun 2018 23:27:45 +0100 Subject: [PATCH 09/14] fix comments --- compiler/sigmatch.nim | 27 ++++++++++-------------- compiler/types.nim | 48 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 52 insertions(+), 23 deletions(-) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index ec13b7557..bdae01d7d 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -633,26 +633,21 @@ proc procTypeRel(c: var TCandidate, f, a: PType): TTypeRelation = else: discard proc typeRangeRel(f, a: PType): TTypeRelation {.noinline.} = - template check_range_in(t: typedesc): untyped = - let - a0 = firstValue[t](a) - a1 = lastValue[t](a) - f0 = firstValue[t](f) - f1 = lastValue[t](f) - if a0 == f0 and a1 == f1: - result = isEqual - elif a0 >= f0 and a1 <= f1: - result = isConvertible - elif a0 <= f1 and f0 <= a1: + template check_range[T](a_first, a_last, f_first, f_last: T): TTypeRelation = + if a_first == f_first and a_last == f_last: + isEqual + elif a_first >= f_first and a_last <= f_last: + isConvertible + elif a_first <= f_last and f_first <= a_last: # X..Y and C..D overlap iff (X <= D and C <= Y) - result = isConvertible + isConvertible else: - result = isNone + isNone if f.isOrdinalType: - check_range_in(BiggestInt) - else: - check_range_in(BiggestFloat) + check_range(firstOrd(a), lastOrd(a), firstOrd(f), lastOrd(f)) + else: + check_range(firstFloat(a), lastFloat(a), firstFloat(f), lastFloat(f)) proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType = diff --git a/compiler/types.nim b/compiler/types.nim index 1fab842cc..83e20c38e 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -88,13 +88,16 @@ proc isPureObject*(typ: PType): bool = proc getOrdValue*(n: PNode): BiggestInt = case n.kind - of nkCharLit..nkUInt64Lit: result = n.intVal - of nkNilLit: result = 0 - of nkHiddenStdConv: result = getOrdValue(n.sons[1]) - else: - #localError(n.info, errOrdinalTypeExpected) - # XXX check usages of getOrdValue - result = high(BiggestInt) + of nkCharLit..nkUInt64Lit: n.intVal + of nkNilLit: 0 + of nkHiddenStdConv: getOrdValue(n.sons[1]) + else: high(BiggestInt) + +proc getFloatValue*(n: PNode): BiggestFloat = + case n.kind + of nkFloatLiterals: n.floatVal + of nkHiddenStdConv: getFloatValue(n.sons[1]) + else: NaN proc isIntLit*(t: PType): bool {.inline.} = result = t.kind == tyInt and t.n != nil and t.n.kind == nkIntLit @@ -623,6 +626,21 @@ proc firstOrd*(t: PType): BiggestInt = internalError(newPartialConfigRef(), "invalid kind for firstOrd(" & $t.kind & ')') result = 0 + +proc firstFloat*(t: PType): BiggestFloat = + case t.kind + of tyFloat..tyFloat128: -Inf + of tyRange: + assert(t.n != nil) # range directly given: + assert(t.n.kind == nkRange) + getFloatValue(t.n.sons[0]) + of tyVar: firstFloat(t.sons[0]) + of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tyStatic, tyInferred: + firstFloat(lastSon(t)) + else: + internalError(newPartialConfigRef(), "invalid kind for firstValue(" & $t.kind & ')') + NaN + proc lastOrd*(t: PType; fixedUnsigned = false): BiggestInt = case t.kind of tyBool: result = 1 @@ -663,6 +681,22 @@ proc lastOrd*(t: PType; fixedUnsigned = false): BiggestInt = internalError(newPartialConfigRef(), "invalid kind for lastOrd(" & $t.kind & ')') result = 0 + +proc lastFloat*(t: PType): BiggestFloat = + case t.kind + of tyFloat..tyFloat128: Inf + of tyVar: lastFloat(t.sons[0]) + of tyRange: + assert(t.n != nil) # range directly given: + assert(t.n.kind == nkRange) + getFloatValue(t.n.sons[1]) + of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tyStatic, tyInferred: + lastFloat(lastSon(t)) + else: + internalError(newPartialConfigRef(), "invalid kind for lastOrd(" & $t.kind & ')') + NaN + + proc lengthOrd*(t: PType): BiggestInt = case t.kind of tyInt64, tyInt32, tyInt: result = lastOrd(t) From 4619ee70580b6dfb12dc3f8063173d5e0c07b9be Mon Sep 17 00:00:00 2001 From: cooldome Date: Mon, 11 Jun 2018 23:20:31 +0100 Subject: [PATCH 10/14] remove underscores --- compiler/sigmatch.nim | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index bdae01d7d..3e278b3dc 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -633,19 +633,19 @@ proc procTypeRel(c: var TCandidate, f, a: PType): TTypeRelation = else: discard proc typeRangeRel(f, a: PType): TTypeRelation {.noinline.} = - template check_range[T](a_first, a_last, f_first, f_last: T): TTypeRelation = - if a_first == f_first and a_last == f_last: + template checkRange[T](afirst, alast, ffirst, flast: T): TTypeRelation = + if afirst == ffirst and alast == flast: isEqual - elif a_first >= f_first and a_last <= f_last: + elif afirst >= ffirst and alast <= flast: isConvertible - elif a_first <= f_last and f_first <= a_last: + elif afirst <= flast and ffirst <= a_last: # X..Y and C..D overlap iff (X <= D and C <= Y) isConvertible else: isNone if f.isOrdinalType: - check_range(firstOrd(a), lastOrd(a), firstOrd(f), lastOrd(f)) + checkRange(firstOrd(a), lastOrd(a), firstOrd(f), lastOrd(f)) else: check_range(firstFloat(a), lastFloat(a), firstFloat(f), lastFloat(f)) From 77f33db3ed5b3f3c116dcb8159e68a8d51daede8 Mon Sep 17 00:00:00 2001 From: cooldome Date: Tue, 12 Jun 2018 09:27:37 +0100 Subject: [PATCH 11/14] style fixes, typos --- compiler/sigmatch.nim | 10 +++++----- doc/manual.rst | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 3e278b3dc..8db14f1cf 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -633,12 +633,12 @@ proc procTypeRel(c: var TCandidate, f, a: PType): TTypeRelation = else: discard proc typeRangeRel(f, a: PType): TTypeRelation {.noinline.} = - template checkRange[T](afirst, alast, ffirst, flast: T): TTypeRelation = - if afirst == ffirst and alast == flast: + template checkRange[T](a0, a1, f0, f1: T): TTypeRelation = + if a0 == f0 and a1 == f1: isEqual - elif afirst >= ffirst and alast <= flast: + elif a0 >= f0 and a1 <= f1: isConvertible - elif afirst <= flast and ffirst <= a_last: + elif a0 <= f1 and f0 <= a1: # X..Y and C..D overlap iff (X <= D and C <= Y) isConvertible else: @@ -647,7 +647,7 @@ proc typeRangeRel(f, a: PType): TTypeRelation {.noinline.} = if f.isOrdinalType: checkRange(firstOrd(a), lastOrd(a), firstOrd(f), lastOrd(f)) else: - check_range(firstFloat(a), lastFloat(a), firstFloat(f), lastFloat(f)) + checkRange(firstFloat(a), lastFloat(a), firstFloat(f), lastFloat(f)) proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType = diff --git a/doc/manual.rst b/doc/manual.rst index 0ebd782bf..9f55654a1 100644 --- a/doc/manual.rst +++ b/doc/manual.rst @@ -741,7 +741,7 @@ For further details, see `Convertible relation Subrange types -------------- -A subrange type is a range of values from an ordinal or float point type (the base +A subrange type is a range of values from an ordinal or floating point type (the base type). To define a subrange type, one must specify it's limiting values: the lowest and highest value of the type: From a877a58f32790d9ef574bcd466b327989cdd6acf Mon Sep 17 00:00:00 2001 From: cooldome Date: Tue, 12 Jun 2018 09:31:45 +0100 Subject: [PATCH 12/14] Fix error message --- compiler/types.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/types.nim b/compiler/types.nim index 83e20c38e..f31096b57 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -638,7 +638,7 @@ proc firstFloat*(t: PType): BiggestFloat = of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tyStatic, tyInferred: firstFloat(lastSon(t)) else: - internalError(newPartialConfigRef(), "invalid kind for firstValue(" & $t.kind & ')') + internalError(newPartialConfigRef(), "invalid kind for firstFloat(" & $t.kind & ')') NaN proc lastOrd*(t: PType; fixedUnsigned = false): BiggestInt = @@ -693,7 +693,7 @@ proc lastFloat*(t: PType): BiggestFloat = of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tyStatic, tyInferred: lastFloat(lastSon(t)) else: - internalError(newPartialConfigRef(), "invalid kind for lastOrd(" & $t.kind & ')') + internalError(newPartialConfigRef(), "invalid kind for lastFloat(" & $t.kind & ')') NaN From 3dd61d6fff794d29ae48f682488819e1c320f346 Mon Sep 17 00:00:00 2001 From: cooldome Date: Tue, 12 Jun 2018 23:20:34 +0100 Subject: [PATCH 13/14] Manual merge --- compiler/types.nim | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/types.nim b/compiler/types.nim index 6120877cb..4c8c244db 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -593,6 +593,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = result = typeToStr[t.kind] result.addTypeFlags(t) + proc firstOrd*(conf: ConfigRef; t: PType): BiggestInt = case t.kind of tyBool, tyChar, tySequence, tyOpenArray, tyString, tyVarargs, tyProxy: From 101f23f3a65fabd5cba2f03070be1e157e572d79 Mon Sep 17 00:00:00 2001 From: cooldome Date: Tue, 12 Jun 2018 23:23:21 +0100 Subject: [PATCH 14/14] manual merge 2 --- compiler/sigmatch.nim | 2 +- compiler/types.nim | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index af0e9648f..915eca8c5 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -649,7 +649,7 @@ proc typeRangeRel(f, a: PType): TTypeRelation {.noinline.} = isNone if f.isOrdinalType: - checkRange(firstOrd(a), lastOrd(a), firstOrd(f), lastOrd(f)) + checkRange(firstOrd(nil, a), lastOrd(nil, a), firstOrd(nil, f), lastOrd(nil, f)) else: checkRange(firstFloat(a), lastFloat(a), firstFloat(f), lastFloat(f)) diff --git a/compiler/types.nim b/compiler/types.nim index 4c8c244db..23350a1e3 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -643,7 +643,7 @@ proc firstFloat*(t: PType): BiggestFloat = internalError(newPartialConfigRef(), "invalid kind for firstFloat(" & $t.kind & ')') NaN -proc lastOrd*(t: PType; fixedUnsigned = false): BiggestInt = +proc lastOrd*(conf: ConfigRef; t: PType; fixedUnsigned = false): BiggestInt = case t.kind of tyBool: result = 1 of tyChar: result = 255 @@ -699,7 +699,7 @@ proc lastFloat*(t: PType): BiggestFloat = NaN -proc lengthOrd*(t: PType): BiggestInt = +proc lengthOrd*(conf: ConfigRef; t: PType): BiggestInt = case t.kind of tyInt64, tyInt32, tyInt: result = lastOrd(conf, t) of tyDistinct: result = lengthOrd(conf, t.sons[0])