본문으로 건너뛰기
토파즈6.0 · 출시 전
다운로드 →

문서 검색

명세 6.0

방향키로 결과를 고르고 Enter를 눌러 여세요.

API 이름, 진단 번호, 규칙 또는 프로젝트 주제를 입력하세요.

    언어 · 2장 · 25개 규칙

    리터럴과 템플릿

    Literal spellings, values, string interpolation, and tagged templates.

    Scope and ownership

    링크

    Literals write values directly in source. This chapter covers their spellings, type families, escapes, interpolation, and template tags.

    Lexical structure owns identifiers, token separation, comments, and source positions.

    Expressions and operators owns unary signs and grouping. Types owns general compatibility and inference. Concurrency owns the behavior of concurrent and its timeout. Library entries own conversion functions and operations on template values.

    Integers and floats

    링크
    EBNF
    1. DecimalDigit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
    2. BinaryDigit = "0" | "1" ;
    3. HexDigit = DecimalDigit | "a" | "b" | "c" | "d" | "e" | "f" ;
    4. DecimalDigits = DecimalDigit ("_"? DecimalDigit)* ;
    5. BinaryDigits = BinaryDigit ("_"? BinaryDigit)* ;
    6. HexDigits = HexDigit ("_"? HexDigit)* ;
    7. IntegerLiteral = DecimalDigits
    8. | "0x" HexDigits
    9. | "0b" BinaryDigits ;
    10. FloatLiteral = DecimalDigits "." DecimalDigits ;

    This manually transcribed excerpt describes numeric tokens in language mode 5.21. Adjacent elements belong to the same token. It omits operator grammar and contextual type rules.

    규칙topaz.literals.rule.integer-spellings

    Integer spellings

    An integer literal uses one of these radix forms.

    RadixPrefixDigits
    10none0123456789
    160x0123456789abcdef
    20b01

    Radix prefixes and hexadecimal letters are lowercase. An uppercase spelling produces TPZ2001 during parsing.

    A leading - is a unary expression operator applied to a literal.

    이유

    Decimal notation expresses magnitudes while binary and hexadecimal notation expose groups of bits. Changing the case of a radix prefix or hexadecimal digit changes neither the value nor the chosen radix. Lowercase removes that spelling choice while preserving the different purposes of the radix forms. A shared integer type keeps arithmetic independent of the chosen radix.

    규칙topaz.literals.rule.numeric-separators

    Numeric digit separators

    In a numeric digit run, _ separates two digits of the selected radix. The run starts and ends with a digit and cannot contain repeated separators. Parsing a malformed numeric token produces TPZ2001.

    이유

    Digit separators make long magnitudes easier to read. Requiring a digit on each side prevents separators from becoming prefixes or suffixes.

    규칙topaz.literals.rule.integer-range

    Integer values and the signed range

    An integer literal has a literal type compatible with int. Values range from -9223372036854775808 through 9223372036854775807. The signed minimum is accepted as -9223372036854775808. An out-of-range integer value produces TPZ5001 during checking.

    이유

    A fixed signed range gives integer values the same bounds across hosts. Rejecting an unrepresentable literal prevents silent truncation before the program runs.

    규칙topaz.literals.rule.decimal-floats

    Decimal float spellings and types

    A float literal has decimal digits on both sides of .. Exponent notation is rejected as a malformed numeric token with TPZ2001 during parsing. A float literal has a literal type compatible with float.

    이유

    A decimal point distinguishes a floating literal from an integer literal. Digits on both sides separate it from member and range punctuation. Positional decimal spelling matches finite-float rendering, which expands the shortest decimal representation into positional notation. Excluding exponent notation keeps source and display on that shared convention. The values use binary64.

    규칙topaz.literals.rule.floating-point

    Decimal float rounding, overflow, and signed zero

    Decimal float literals round to the nearest binary64 value. An exact tie selects the value with an even final significand bit. Overflow produces infinity. Underflow can produce a subnormal value or zero. Unary minus retains the sign of zero. Interpolation writes the infinities as inf and -inf, and the two zeros as 0.0 and -0.0. Decimal spelling still requires a point with digits on both sides; exponent spelling is rejected.

    이유

    Binary64 gives floating literals a common numeric representation. Defined rounding and signed zero make boundary values reproducible across the literal and arithmetic paths.

    Booleans, null, and unit

    링크
    EBNF
    1. BooleanLiteral = "true" | "false" ;
    2. NullLiteral = "null" ;
    3. UnitLiteral = "(" ")" ;

    Parentheses containing an expression belong to the expression grammar.

    규칙topaz.literals.rule.scalar-types

    Boolean, null, and unit types

    SpellingType
    trueboolean literal type compatible with bool
    falseboolean literal type compatible with bool
    nullnull literal type
    ()unit type ()

    이유

    Boolean values, absence, and unit represent distinct concepts. Their separate types prevent an absent value or a completed action from becoming an implicit Boolean.

    For null compatibility, the contextual typing of None(), and restrictions on the binding name None, see Types and Bindings and scope.

    Duration literals

    링크
    EBNF
    1. DurationLiteral = DecimalDigits DurationUnit ;
    2. DurationUnit = "ms" | "s" | "m" ;

    DecimalDigits is defined in the numeric grammar above.

    Concurrency owns the complete concurrent expression and timeout behavior.

    규칙topaz.literals.rule.duration-form

    Duration literals are ordinary values

    A duration literal attaches a lowercase ms, s, m suffix to a decimal integer magnitude. It denotes an ordinary Duration value, including in bindings, function arguments and results, parenthesized expressions, and concurrent(timeout: ...). Duration has no type arguments and does not implicitly convert to or from int or float. The same literal conversion and range checks apply in every expression position. Operations follow the Duration values rule.

    Arithmetic, comparison, display, and toMillis follow Duration operations.

    이유

    A unit suffix states the time scale beside the magnitude. The same literal denotes Duration in an ordinary expression and in a timeout; binding or parenthesizing that value does not change its admission. Duration remains distinct from numeric types so an integer cannot silently acquire a time unit.

    규칙topaz.literals.rule.duration-values

    Duration values and operations

    SuffixUnitMilliseconds per unit
    msmillisecond1
    ssecond1000
    mminute60000

    A Duration stores from 0 through 18446744073709551615 milliseconds. An out-of-range duration literal produces TPZ5001 during checking.

    Two Duration values support addition and subtraction. Multiplication takes a Duration and an int in either order, as in d * n and n * d. Construct a duration from an integer with 1ms * n. Duration has no division and no function for converting a number to Duration.

    Eq compares millisecond counts for equality. Order compares those counts numerically. Display produces a decimal millisecond literal such as 1500ms, which reads back as the same value. toMillis() -> int returns the millisecond count. Duration has no JSON capability in 6.0.

    An overflowing sum or product, a subtraction below zero, any negative integer multiplier, or a millisecond count outside the int range stops with runtime TPZ4004. These faults follow the fault cleanup rule.

    Runtime range failures use TPZ4004. Timeout evaluation follows concurrent deadlines.

    이유

    Every Duration stores milliseconds, so operations use one unit. A literal and integer multiplication provide one way to construct a duration from a number. The millisecond display reads back as the same value.

    Length literals

    링크
    EBNF
    1. LengthLiteral = DecimalMagnitude LengthUnit ;
    2. DecimalMagnitude = DecimalDigits ("." DecimalDigits)? ;
    3. LengthUnit = "pt" | "mm" | "cm" | "in" | "em" ;

    DecimalDigits is defined in the numeric grammar above.

    규칙topaz.literals.rule.length-literals

    Length spellings and types

    A length literal attaches its lowercase unit directly to a decimal integer or decimal fraction. Radix and exponent notation are not length-literal forms.

    SuffixLiteral type
    ptLength<Pt>
    mmLength<Mm>
    cmLength<Cm>
    inLength<In>
    emLength<Em>

    The suffix determines the compiler-owned length type. Literal formation rejects an unrepresentable result with TPZ5001 during checking.

    이유

    Typed units let page dimensions and font-relative dimensions enter layout APIs directly. Keeping em distinct from physical lengths prevents a font size from being assumed implicitly.

    Length conversions and arithmetic belong to their API entries. See Pending contracts for precision and exact literal endpoints.

    규칙topaz.literals.rule.length-precision

    Length rounding and literal boundaries

    A Length literal is converted from its exact decimal value, including its sign. It rounds to the nearest multiple of the unit step below. An exact midpoint selects the even multiple.

    UnitStep in that unitMinimum input, includedUpper input limit, excluded
    pt1/65536-18446744073709551617/13107218446744073709551615/131072
    mm127/23592960-2342736497361113055359/47185920156182433157407537007/3145728
    cm127/235929600-2342736497361113055359/471859200156182433157407537007/31457280
    in1/4718592-18446744073709551617/94371846148914691236517205/3145728
    em1/65536-18446744073709551617/13107218446744073709551615/131072

    The fractions are exact mathematical values. Write a decimal value followed immediately by its unit in source. A literal outside this interval produces TPZ5001 during checking. Equality and the public unit-conversion methods observe the rounded result.

    이유

    Exact decimal conversion fixes a document dimension before layout. A shared point grid aligns physical unit conversions, and ties-to-even rounding avoids directional bias at exact midpoints.

    Strings and interpolation

    링크
    EBNF
    1. StringLiteral = SingleLineString | MultilineString ;
    2. SingleLineString = '"' SingleLinePart* '"' ;
    3. MultilineString = '"""' MultilinePart* '"""' ;
    4. SingleLinePart = SingleLineText | Escape | Interpolation ;
    5. MultilinePart = MultilineText | Escape | Interpolation ;
    6. Escape = '\' ("n" | "r" | "t" | '\' | '"' | "{" | "}") ;
    7. Interpolation = "{" Expression "}" ;

    SingleLineText and MultilineText are scanner-delimited text runs. A physical LF, CRLF, or CR is a line break. Inside a single-line string, text and interpolation reject physical line breaks. Multiline text uses them for opening removal and indentation, then stores LF. Escapes and inserted string values retain their carriage returns.

    규칙topaz.literals.rule.string-parts

    String delimiters and interpolation

    String formOpening and closing delimiter
    single-line"
    multiline"""

    An unescaped { begins interpolation containing an expression followed by }. An empty interpolation produces TPZ2001 during parsing.

    이유

    Interpolation joins evaluated values with literal text through one string grammar. Multiline delimiters allow document text to retain visible line structure in source.

    규칙topaz.literals.rule.string-escapes

    String escape values

    Single-line and multiline strings use these escapes, including strings tagged r, sh, sql.

    EscapeValueCode point
    \nline feedU+000A
    \rcarriage returnU+000D
    \ttabU+0009
    \\backslashU+005C
    \"quotation markU+0022
    \{opening braceU+007B
    \}closing braceU+007D

    An unknown escape produces TPZ0004 during lexing for every tag. Write an escaped backslash when a literal backslash is intended.

    이유

    One escape grammar gives a backslash the same meaning in strings and every template tag. Explicit escapes distinguish delimiters from text.

    규칙topaz.literals.rule.single-line-boundaries

    Single-line string boundaries

    A single-line string cannot cross a physical LF, CRLF, or CR line break, including inside interpolation. Crossing one produces TPZ0003 during lexing. An escaped carriage return or a carriage return in an inserted string remains character data.

    이유

    A physical line break ends an unfinished single-line string before later source is consumed as text. Equivalent file line endings must produce the same rejection.

    규칙topaz.literals.rule.string-types

    String literal and interpolation types

    Ordinary strings use the following type selection.

    InterpolationType
    absentstring literal type
    presentstring

    이유

    A fixed literal has a known value that type checking can retain. Interpolation depends on evaluated expressions, so its result uses the general string type.

    규칙topaz.literals.rule.interpolation-values

    ByteBuffer interpolation

    Interpolating a value whose type contains ByteBuffer in a string or tagged template produces TPZ5001 during checking.

    이유

    ByteBuffer is mutable storage rather than text. Rejecting its implicit display keeps byte decoding and the choice of character encoding explicit.

    See Pending contracts for value formatting, evaluation order, and the number of evaluations.

    규칙topaz.literals.rule.interpolation-evaluation

    Ordinary string interpolation order and conversion

    In an ordinary string, each interpolation expression is evaluated once in source order. A nested interpolation completes before the next outer expression. The value then uses the standard renderer, with no automatic call to a user-defined show method. Inserted spaces and newlines remain unchanged.

    Value familyConversion
    ScalarsStrings insert their text. Integers and floats use numeric text. Booleans, null, and unit use their literal spellings.
    Arrays and structural recordsElements and named fields render recursively, separated by commas.
    Option and ResultThe constructor name surrounds the rendered payload. None has no payload.
    Nominal valuesRecords, enum variants, and newtypes retain their nominal identity and recursively render their contents.
    Collections and rangesMap and Set use their standard collection displays. Ranges show their endpoints and optional step.
    Functions and resourcesFunctions, files, namespaces, and opaque values use their standard display labels.
    Library valuesBytes use hexadecimal text. Path, Regex, Date, URL, BigInt, Decimal, and other built-in values use their standard representations.
    TemplatesDisplay a summary with the tag and counts of parts and values.

    A value whose type contains ByteBuffer produces TPZ5001 during checking, including inside arrays, records, unions, and nominal fields.

    이유

    Evaluating each expression once in source order makes effects predictable. Preserving inserted whitespace lets document content determine its own line and spacing structure.

    규칙topaz.literals.rule.string-scalar-data

    Preserved Unicode string data

    Literal text, inserted strings, and template text preserve their Unicode scalar sequence after the specified escape, physical-line-break, indentation, and blank-line processing. They do not apply Unicode normalization or remove Default_Ignorable_Code_Point scalars. Composed and decomposed text can therefore produce different UTF-8 bytes. A name inside an interpolation follows the identifier rules because it is part of the expression.

    이유

    Text values may carry externally supplied spelling, file contents, or protocol bytes. Implicit Unicode normalization or removal of invisible scalars would lose that data. Names use NFC to give bindings a canonical source spelling. A string preserves its scalar sequence after the separately specified source-text transformations.

    Multiline strings

    링크
    규칙topaz.literals.rule.multiline-opening

    Multiline opening line break

    In a multiline string, one physical LF, CRLF, or CR line break immediately after the opening delimiter is removed from the value. CRLF is one line break.

    이유

    Removing the opening line break lets a document text block start on the line after its delimiter without adding an empty first line.

    규칙topaz.literals.rule.multiline-indent

    Multiline closing indentation

    When the closing delimiter follows spaces and tabs on its own line, that exact prefix is removed from each nonblank text line. Physical LF, CRLF, and CR each start a new line for this check. A nonblank line without that prefix produces TPZ0006 during lexing. The closing indentation is also removed.

    이유

    Removing the closing delimiter prefix separates source indentation from document indentation. Checking every physical line-ending form prevents file conversion from bypassing the indentation check.

    규칙topaz.literals.rule.multiline-newlines

    Multiline newline values

    Physical LF, CRLF, and CR line breaks in multiline text become LF. CRLF becomes one LF. A newline before the closing indentation remains in the value. Normalization applies to source text before escape decoding and value insertion. An escaped carriage return or a carriage return in an inserted string remains character data. Interpolation expressions use the source expression grammar.

    이유

    Treating physical LF, CRLF, and CR alike keeps document text stable when a file changes line-ending format. Escapes and inserted values preserve intentional carriage-return data.

    규칙topaz.literals.rule.multiline-boundaries

    Whitespace and interpolation in multiline strings

    A multiline source text line containing just spaces (U+0020) and tabs (U+0009) contributes an empty line. Its line break remains. This applies with or without closing indentation, in ordinary and tagged strings. Removal happens before escape decoding and value insertion. Escaped and inserted whitespace remains data. Nonblank indentation compares the exact source prefix, without expanding tabs. An interpolated value cannot supply missing indentation. A prefix mismatch produces TPZ0006 during lexing. Physical LF, CRLF, and CR start new text lines and become LF in the string value.

    이유

    Blank source lines remain empty when an editor changes their indentation. This keeps document text independent of formatting. Source whitespace is removed before escapes and interpolation, so explicit character data remains intact. Exact nonblank prefixes avoid dependence on an editor tab width.

    Tagged templates

    링크
    EBNF
    1. TemplateLiteral = TemplateTag StringLiteral ;
    2. TemplateTag = "r" | "sh" | "sql" ;

    StringLiteral is defined above. Every tag uses its complete escape grammar, including the same delimiter and interpolation-brace escapes.

    Tag-specific processing and operations on the resulting template value belong to their library entries.

    규칙topaz.literals.rule.template-tags

    Registered template tags

    The template tags are r, sh, sql. Write the tag immediately before a single-line or triple-quoted string. A different immediately attached identifier produces TPZ2002 during parsing.

    이유

    The registry keeps template consumers explicit and catches misspelled tags. Paths use the ordinary Path.from call, which accepts both literal and computed strings and returns the same validated Path type. The former p tag produced a template with slash-only display conversion, so it is removed rather than retain a second path-looking spelling with different validation. This follows the Path.from-only owner decision and the one-way-to-say-it criterion. Joining path parts safely is expressed by Path.join. Reading text as a path is expressed by Path.from. A path template tag adds no distinct intent to either operation.

    규칙topaz.literals.rule.template-types

    Template value types

    A registered tagged template is checked as a template value.

    이유

    A distinct template type preserves the boundary between structured text and an ordinary string. Consumers can inspect the tag and literal parts before interpreting them.

    Each registered tag uses the string escape grammar above. Construction, accessors, and display are defined below. Construct a path with Path.from applied to an ordinary string; p is not a registered template tag.

    규칙topaz.literals.rule.template-runtime

    Tagged-template construction and display

    Registered tags construct template values from cooked text parts and expressions evaluated once in source order. There is one more text part than interpolation values. tag returns the tag as a string. parts returns an array value of the literal text segments under value semantics. Interpolated values remain separate and have no public accessor.

    TagConstruction and string-interpolation display
    rKeeps the pattern structure without compiling or validating a regular expression. Display reports the tag and counts of parts and values.
    shKeeps text and values separate without executing a command. Display reports the tag and counts.
    sqlKeeps query text and values separate without executing a query or inserting values into query text. Display reports the tag and counts.

    A template value cannot be passed where string is required. Use ordinary string interpolation to obtain its display. All tags use the shared string escape grammar. For example, r"\\d" preserves a regex backslash, and \{ and \} preserve literal braces.

    이유

    Keeping inserted values separate from text lets a consumer interpret their roles without reconstructing them from a string. Construction does not execute the embedded command or query. Joining path parts safely is expressed by Path.join. Reading text as a path is expressed by Path.from. A path template tag adds no distinct intent to either operation.

    Constructing paths

    링크
    규칙topaz.literals.rule.path-construction

    Construct a normalized Path with Path.from

    Path.from follows the Path construction contract. That rule defines normalization, input failures and removed construction members.

    이유

    Path.from gives literal, interpolated and computed text one conversion to a relative path. Its construction contract owns normalization and input failures. The old cwdRelative and project factories performed the same pure normalization. Their different error prefixes did not express a distinct operation. The old normalize member returned its receiver. Path.join safely combines path parts, while Path.from reads text as a path. The removed p tag added no distinct intent to either operation.

    Examples and counterexamples

    링크

    Integer bases and decimal floats

    링크
    example.tpzInteger bases and decimal floats
    1. let decimal: int = 1_000
    2. let hexadecimal: int = 0xca_fe
    3. let binary: int = 0b1010_0101
    4. let fraction: float = 1_234.5_6
    5. let minimum: int = -9223372036854775808
    6. let maximum: int = 9223372036854775807
    7. let value: int = 1_0
    기대 출력종료 코드 0
    $ topaz check example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    Repeated digit separator

    링크
    example.tpzRepeated digit separator플레이그라운드 열기 →
    1. let value = 1__0
    기록된 출력종료 코드 1
    표준 출력 없음.
    error[TPZ2001]: malformed numeric literal
     --> example.tpz:1:13
      |
    1 | let value = 1__0
      |             ^^^^
    
    example.tpz: 1 diagnostic
    
    $ topaz check example.tpz --compiler self · 기록에 사용한 토파즈 5.21.3
    기대 결과

    기대 결과

    거절 단계 parse. 종료 코드가 0이 아닙니다.

    • TPZ2001 →

      malformed-numeric-literal at example.tpz:1:13

    관측한 단언 · 통과 · 5.21.3

    종료 코드 1.

    표준 출력 없음.

    관측한 표준 오류 출력
    1. error[TPZ2001]: malformed numeric literal
    2. --> example.tpz:1:13
    3. |
    4. 1 | let value = 1__0
    5. | ^^^^
    6. example.tpz: 1 diagnostic
    • 통과 · checking TPZ2001; cause malformed-numeric-literal; primary location asserted; additional diagnostics allow
    • 통과 · expected nonzero; observed 1

    The intended cause is the repeated underscore inside the numeric token. Replace it with one underscore or remove it.

    Exponent spelling

    링크
    example.tpzExponent spelling플레이그라운드 열기 →
    1. let value = 1e3
    기록된 출력종료 코드 1
    표준 출력 없음.
    error[TPZ2001]: malformed numeric literal
     --> example.tpz:1:13
      |
    1 | let value = 1e3
      |             ^^^
    
    example.tpz: 1 diagnostic
    
    $ topaz check example.tpz --compiler self · 기록에 사용한 토파즈 5.21.3
    기대 결과

    기대 결과

    거절 단계 parse. 종료 코드가 0이 아닙니다.

    • TPZ2001 →

      malformed-numeric-literal at example.tpz:1:13

    관측한 단언 · 통과 · 5.21.3

    종료 코드 1.

    표준 출력 없음.

    관측한 표준 오류 출력
    1. error[TPZ2001]: malformed numeric literal
    2. --> example.tpz:1:13
    3. |
    4. 1 | let value = 1e3
    5. | ^^^
    6. example.tpz: 1 diagnostic
    • 통과 · checking TPZ2001; cause malformed-numeric-literal; primary location asserted; additional diagnostics allow
    • 통과 · expected nonzero; observed 1

    Use 1000.0 when the intended value is one thousand as a float.

    Integer magnitude above the signed range

    링크
    example.tpzInteger magnitude above the signed range플레이그라운드 열기 →
    1. let value = 9223372036854775808
    기록된 출력종료 코드 1
    표준 출력 없음.
    error[TPZ5001]: integer literal `9223372036854775808` is out of range
     --> example.tpz:1:13
      |
    1 | let value = 9223372036854775808
      |             ^^^^^^^^^^^^^^^^^^^
    
    example.tpz: 1 type diagnostic
    
    $ topaz check example.tpz --compiler self · 기록에 사용한 토파즈 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5001 →

      integer-literal-out-of-range at example.tpz:1:13

    관측한 단언 · 통과 · 5.21.3

    종료 코드 1.

    표준 출력 없음.

    관측한 표준 오류 출력
    1. error[TPZ5001]: integer literal `9223372036854775808` is out of range
    2. --> example.tpz:1:13
    3. |
    4. 1 | let value = 9223372036854775808
    5. | ^^^^^^^^^^^^^^^^^^^
    6. example.tpz: 1 type diagnostic
    • 통과 · checking TPZ5001; cause integer-literal-out-of-range; primary location asserted; additional diagnostics allow
    • 통과 · expected nonzero; observed 1

    Boolean, null, and unit values

    링크
    example.tpzBoolean, null, and unit values
    1. let enabled: bool = true
    2. let disabled: bool = false
    3. let absent = null
    4. let completed: () = ()
    기록된 출력종료 코드 0
    example.tpz: types-ok (1 module)
    example.tpz: resolve-ok (1 module)
    
    $ topaz check example.tpz · 기록에 사용한 토파즈 5.21.3
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    관측한 단언 · 통과 · 5.21.3

    종료 코드 0.

    관측한 표준 출력
    1. example.tpz: types-ok (1 module)
    2. example.tpz: resolve-ok (1 module)

    표준 오류 출력 없음.

    • 통과 · expected 0; observed 0

    Duration in its timeout context

    링크
    example.tpzDuration in its timeout context
    1. let result = concurrent(timeout: 1_500ms) {
    2. value: 1
    3. } else {
    4. { value: 0 }
    5. }
    기록된 출력종료 코드 0
    example.tpz: types-ok (1 module)
    example.tpz: resolve-ok (1 module)
    
    $ topaz check example.tpz · 기록에 사용한 토파즈 5.21.3
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    관측한 단언 · 통과 · 5.21.3

    종료 코드 0.

    관측한 표준 출력
    1. example.tpz: types-ok (1 module)
    2. example.tpz: resolve-ok (1 module)

    표준 오류 출력 없음.

    • 통과 · expected 0; observed 0

    A Duration value outside a timeout

    링크
    example.tpzA Duration value outside a timeout플레이그라운드 열기 →
    1. let delay = 3s
    2. let saved: Duration = (delay)
    기대 출력종료 코드 0
    표준 출력 없음.
    $ topaz check example.tpz --compiler self --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    The stable example identity formerly tested the SELF-only context restriction. Its old fixture, assertion plan and receipt remain historical evidence. The current version expects an ordinary Duration binding to succeed; the original receipt is not evidence of this revised contract.

    Length suffixes and types

    링크
    example.tpzLength suffixes and types
    1. let points: Length<Pt> = 12pt
    2. let millimeters: Length<Mm> = 2.5mm
    3. let centimeters: Length<Cm> = 1cm
    4. let inches: Length<In> = 0.5in
    5. let relative: Length<Em> = 1.25em
    기록된 출력종료 코드 0
    example.tpz: types-ok (1 module)
    example.tpz: resolve-ok (1 module)
    
    $ topaz check example.tpz · 기록에 사용한 토파즈 5.21.3
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    관측한 단언 · 통과 · 5.21.3

    종료 코드 0.

    관측한 표준 출력
    1. example.tpz: types-ok (1 module)
    2. example.tpz: resolve-ok (1 module)

    표준 오류 출력 없음.

    • 통과 · expected 0; observed 0

    Escapes and an interpolated value

    링크
    example.tpzEscapes and an interpolated value
    1. import std.io
    2. let count = 3
    3. io.writeLine("Topaz {count}: \"\{ok\}\"\\")
    4. io.writeLine("first\nsecond\tend")
    기록된 출력종료 코드 0
    Topaz 3: "{ok}"\
    first
    second	end
    
    $ topaz run example.tpz · 기록에 사용한 토파즈 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. Topaz 3: "{ok}"\
    2. first
    3. second end
    관측한 단언 · 통과 · 5.21.3

    종료 코드 0.

    관측한 표준 출력
    1. Topaz 3: "{ok}"\
    2. first
    3. second end

    표준 오류 출력 없음.

    • 통과 · expected 0; observed 0
    • 통과 · stdout matches the authored expectation
    • 통과 · stderr matches the authored expectation

    Unknown escape

    링크
    example.tpzUnknown escape플레이그라운드 열기 →
    1. let text = "bad\q"
    기록된 출력종료 코드 1
    표준 출력 없음.
    error[TPZ0004]: invalid escape `\q` in a string literal
     --> example.tpz:1:16
      |
    1 | let text = "bad\q"
      |                ^^
    
    example.tpz: 1 diagnostic
    
    $ topaz check example.tpz --compiler self · 기록에 사용한 토파즈 5.21.3
    기대 결과

    기대 결과

    거절 단계 lex. 종료 코드가 0이 아닙니다.

    관측한 단언 · 통과 · 5.21.3

    종료 코드 1.

    표준 출력 없음.

    관측한 표준 오류 출력
    1. error[TPZ0004]: invalid escape `\q` in a string literal
    2. --> example.tpz:1:16
    3. |
    4. 1 | let text = "bad\q"
    5. | ^^
    6. example.tpz: 1 diagnostic
    • 통과 · checking TPZ0004; cause invalid-string-escape; primary location asserted; additional diagnostics allow
    • 통과 · expected nonzero; observed 1

    Replace the unknown escape with a supported escape or write an escaped backslash when a literal backslash is intended.

    Multiline indentation and final newline

    링크
    example.tpzMultiline indentation and final newline
    1. import std.io
    2. io.writeLine("""
    3. first
    4. second
    5. """)
    기록된 출력종료 코드 0
    first
    second
    
    
    $ topaz run example.tpz · 기록에 사용한 토파즈 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. first
    2. second
    관측한 단언 · 통과 · 5.21.3

    종료 코드 0.

    관측한 표준 출력
    1. first
    2. second

    표준 오류 출력 없음.

    • 통과 · expected 0; observed 0
    • 통과 · stdout matches the authored expectation
    • 통과 · stdout matches the authored expectation
    • 통과 · stdout matches the authored expectation
    • 통과 · stderr matches the authored expectation

    The four registered template tags

    링크
    example.tpzThe four registered template tags플레이그라운드 열기 →
    1. let regexTemplate = r"a+"
    2. let shellTemplate = sh"echo hello"
    3. let sqlTemplate = sql"select {1}"
    기대 출력종료 코드 0
    $ topaz check example.tpz --compiler self --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    Tag outside the registry

    링크
    example.tpzTag outside the registry플레이그라운드 열기 →
    1. let value = html"hello"
    기록된 출력종료 코드 1
    표준 출력 없음.
    error[TPZ2002]: unknown template tag `html`; the registry is `p`, `r`, `sh`, `sql`
     --> example.tpz:1:13
      |
    1 | let value = html"hello"
      |             ^^^^
    
    example.tpz: 1 diagnostic
    
    $ topaz check example.tpz --compiler self · 기록에 사용한 토파즈 5.21.3
    기대 결과

    기대 결과

    거절 단계 parse. 종료 코드가 0이 아닙니다.

    관측한 단언 · 통과 · 5.21.3

    종료 코드 1.

    표준 출력 없음.

    관측한 표준 오류 출력
    1. error[TPZ2002]: unknown template tag `html`; the registry is `p`, `r`, `sh`, `sql`
    2. --> example.tpz:1:13
    3. |
    4. 1 | let value = html"hello"
    5. | ^^^^
    6. example.tpz: 1 diagnostic
    • 통과 · checking TPZ2002; cause unknown-template-tag; primary location asserted; additional diagnostics allow
    • 통과 · expected nonzero; observed 1

    The counterexample uses the tag html. The program does not invoke an HTML operation.

    Blank source lines stay empty while CRLF and CR become LF

    링크
    example.tpzBlank source lines stay empty while CRLF and CR become LF플레이그라운드 열기 →
    1. import std.io
    2. let part = "x"
    3. let value = """
    4. A{part}
    5. B C
    6. """
    7. io.writeLine(value.encodeUtf8().toHex())
    기대 출력종료 코드 0
    41780a0a420a430a
    
    $ topaz run example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 41780a0a420a430a

    A tab prefix is not two spaces

    링크
    example.tpzA tab prefix is not two spaces플레이그라운드 열기 →
    1. let value = """
    2. first
    3. """
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 lex. 종료 코드가 0이 아닙니다.

    • TPZ0006 →

      multiline-closing-indent-mismatch at example.tpz:2:1

    Interpolation cannot supply source indentation

    링크
    example.tpzInterpolation cannot supply source indentation플레이그라운드 열기 →
    1. let padding = " "
    2. let value = """
    3. {padding}body
    4. """
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 lex. 종료 코드가 0이 아닙니다.

    • TPZ0006 →

      multiline-closing-indent-mismatch at example.tpz:3:1

    Observe ties-to-even through equality and unit conversion

    링크
    example.tpzObserve ties-to-even through equality and unit conversion플레이그라운드 열기 →
    1. import std.io
    2. let half = 0.00000762939453125pt
    3. let oneAndHalf = 0.00002288818359375pt
    4. let two = 0.000030517578125pt
    5. io.writeLine("{half == 0pt}|{oneAndHalf == two}|{-half == 0pt}")
    6. io.writeLine("{(25.4mm).toPt() == 72pt}|{(2.54cm).toPt() == 72pt}|{(1in).toPt() == 72pt}")
    7. io.writeLine("{0.00000762939453125em == 0em}|{0.00002288818359375em == 0.000030517578125em}")
    기대 출력종료 코드 0
    true|true|true
    true|true|true
    true|true
    
    $ topaz run example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. true|true|true
    2. true|true|true
    3. true|true

    Decimal values inside both limits for every unit

    링크
    example.tpzDecimal values inside both limits for every unit플레이그라운드 열기 →
    1. let good0 = -140737488355328.000007629394531250000000000000pt
    2. let good1 = 140737488355327.999992370605468749999999999999pt
    3. let good2 = -49649058392018.488891580369737413194444444444mm
    4. let good3 = 49649058392018.488886197408040364583333333333mm
    5. let good4 = -4964905839201.848889158036973741319444444444cm
    6. let good5 = 4964905839201.848888619740804036458333333333cm
    7. let good6 = -1954687338268.444444550408257378472222222222in
    8. let good7 = 1954687338268.444444338480631510416666666666in
    9. let good8 = -140737488355328.000007629394531250000000000000em
    10. let good9 = 140737488355327.999992370605468749999999999999em
    기대 출력종료 코드 0
    $ topaz check example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    Observe rounding, infinity, subnormals, and signed zero

    링크
    example.tpzObserve rounding, infinity, subnormals, and signed zero플레이그라운드 열기 →
    1. import std.io
    2. let tieEven = 1.00000000000000011102230246251565404236316680908203125
    3. let tieNext = 1.00000000000000033306690738754696212708950042724609375
    4. let overflow = 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0
    5. let tiny = 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
    6. let subnormal = 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005
    7. let twiceSubnormal = 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
    8. io.writeLine("{tieEven == 1.0}|{tieNext == 1.0000000000000004}")
    9. io.writeLine("{overflow}|{-overflow}")
    10. io.writeLine("{tiny}|{-tiny}|{1.0 / tiny}|{1.0 / -tiny}")
    11. io.writeLine("{subnormal > 0.0}|{subnormal < twiceSubnormal}|{subnormal + subnormal == twiceSubnormal}")
    기대 출력종료 코드 0
    true|true
    inf|-inf
    0.0|-0.0|inf|-inf
    true|true|true
    
    $ topaz run example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. true|true
    2. inf|-inf
    3. 0.0|-0.0|inf|-inf
    4. true|true|true

    Exponent spelling is not a decimal float literal

    링크
    example.tpzExponent spelling is not a decimal float literal플레이그라운드 열기 →
    1. let value = 1.0e3
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 parse. 종료 코드가 0이 아닙니다.

    • TPZ2001 →

      malformed-numeric-literal at example.tpz:1:13

    Nested interpolations evaluate each occurrence once

    링크
    example.tpzNested interpolations evaluate each occurrence once플레이그라운드 열기 →
    1. import std.io
    2. function mark(n: int) -> int { io.writeLine("mark {n}")
    3. n }
    4. let value = "outer {mark(1)}|{"inner {mark(2)}"}|{mark(3)}"
    5. io.writeLine(value)
    기대 출력종료 코드 0
    mark 1
    mark 2
    mark 3
    outer 1|inner 2|3
    
    $ topaz run example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. mark 1
    2. mark 2
    3. mark 3
    4. outer 1|inner 2|3

    Display scalars and nested values with the standard renderer

    링크
    example.tpzDisplay scalars and nested values with the standard renderer플레이그라운드 열기 →
    1. import std.io
    2. let row = { count: 3 }
    3. let selected: Option<int> = Some(3)
    4. let missing: Option<int> = None()
    5. let ok: Result<int, string> = Ok(4)
    6. let err: Result<int, string> = Err("no")
    7. io.writeLine("{7}|{2.5}|{true}|{()}|{null}")
    8. io.writeLine("{[1, 2]}|{row}|{selected}|{missing}|{ok}|{err}")
    기대 출력종료 코드 0
    7|2.5|true|()|null
    [1, 2]|{ count: 3 }|Some(3)|None|Ok(4)|Err(no)
    
    $ topaz run example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 7|2.5|true|()|null
    2. [1, 2]|{ count: 3 }|Some(3)|None|Ok(4)|Err(no)

    An aggregate containing ByteBuffer cannot be interpolated

    링크
    example.tpzAn aggregate containing ByteBuffer cannot be interpolated플레이그라운드 열기 →
    1. let buffer = ByteBuffer.allocate(1)
    2. let nested = [buffer]
    3. let value = "{nested}"
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5001 →

      byte-buffer-interpolation at example.tpz:3:15

    Inspect templates without executing or validating their contents

    링크
    example.tpzInspect templates without executing or validating their contents플레이그라운드 열기 →
    1. import std.io
    2. import std.path { Path }
    3. function mark(n: int) -> int { io.writeLine("mark {n}")
    4. n }
    5. let segment = "a\\b"
    6. let path = match (Path.from("dir\\{segment}/{mark(1)}")) {
    7. case Ok(value) => value.toString()
    8. case Err(error) => error
    9. }
    10. let pattern = r"[{mark(2)}"
    11. let command = sh"echo {mark(3)}"
    12. let query = sql"SELECT {mark(4)}"
    13. io.writeLine("{path}")
    14. io.writeLine("{pattern}|{command}|{query}")
    15. io.writeLine("{query.tag}|{query.parts.length}|{query.parts[0]}|{query.parts[1]}")
    16. let mut parts = query.parts
    17. parts[0] = "changed"
    18. io.writeLine("{query.parts[0]}")
    기대 출력종료 코드 0
    mark 1
    mark 2
    mark 3
    mark 4
    dir/a/b/1
    <r template, 2 part(s), 1 interpolation(s)>|<sh template, 2 part(s), 1 interpolation(s)>|<sql template, 2 part(s), 1 interpolation(s)>
    sql|2|SELECT |
    SELECT 
    
    $ topaz run example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. mark 1
    2. mark 2
    3. mark 3
    4. mark 4
    5. dir/a/b/1
    6. <r template, 2 part(s), 1 interpolation(s)>|<sh template, 2 part(s), 1 interpolation(s)>|<sql template, 2 part(s), 1 interpolation(s)>
    7. sql|2|SELECT |
    8. SELECT

    The parts accessor returns an array value under value semantics. Changing parts leaves query.parts unchanged.

    A template value cannot initialize string

    링크
    example.tpzA template value cannot initialize string플레이그라운드 열기 →
    1. let value: string = sql"SELECT 1"
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    Tagged interpolation rejects ByteBuffer too

    링크
    example.tpzTagged interpolation rejects ByteBuffer too플레이그라운드 열기 →
    1. let buffer = ByteBuffer.allocate(1)
    2. let value = sql"SELECT {buffer}"
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5001 →

      byte-buffer-interpolation at example.tpz:2:25

    Reject a value past the negative pt limit

    링크
    example.tpzReject a value past the negative pt limit플레이그라운드 열기 →
    1. let bad0 = -140737488355328.000007629394531250000000000001pt
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5001 →

      length-literal-not-representable at example.tpz:1:12

    Reject a value past the positive pt limit

    링크
    example.tpzReject a value past the positive pt limit플레이그라운드 열기 →
    1. let bad1 = 140737488355327.999992370605468750000000000000pt
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5001 →

      length-literal-not-representable at example.tpz:1:12

    Reject a value past the negative mm limit

    링크
    example.tpzReject a value past the negative mm limit플레이그라운드 열기 →
    1. let bad2 = -49649058392018.488891580369737413194444444445mm
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5001 →

      length-literal-not-representable at example.tpz:1:12

    Reject a value past the positive mm limit

    링크
    example.tpzReject a value past the positive mm limit플레이그라운드 열기 →
    1. let bad3 = 49649058392018.488886197408040364583333333334mm
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5001 →

      length-literal-not-representable at example.tpz:1:12

    Reject a value past the negative cm limit

    링크
    example.tpzReject a value past the negative cm limit플레이그라운드 열기 →
    1. let bad4 = -4964905839201.848889158036973741319444444445cm
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5001 →

      length-literal-not-representable at example.tpz:1:12

    Reject a value past the positive cm limit

    링크
    example.tpzReject a value past the positive cm limit플레이그라운드 열기 →
    1. let bad5 = 4964905839201.848888619740804036458333333334cm
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5001 →

      length-literal-not-representable at example.tpz:1:12

    Reject a value past the negative in limit

    링크
    example.tpzReject a value past the negative in limit플레이그라운드 열기 →
    1. let bad6 = -1954687338268.444444550408257378472222222223in
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5001 →

      length-literal-not-representable at example.tpz:1:12

    Reject a value past the positive in limit

    링크
    example.tpzReject a value past the positive in limit플레이그라운드 열기 →
    1. let bad7 = 1954687338268.444444338480631510416666666667in
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5001 →

      length-literal-not-representable at example.tpz:1:12

    Reject a value past the negative em limit

    링크
    example.tpzReject a value past the negative em limit플레이그라운드 열기 →
    1. let bad8 = -140737488355328.000007629394531250000000000001em
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5001 →

      length-literal-not-representable at example.tpz:1:12

    Reject a value past the positive em limit

    링크
    example.tpzReject a value past the positive em limit플레이그라운드 열기 →
    1. let bad9 = 140737488355327.999992370605468750000000000000em
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5001 →

      length-literal-not-representable at example.tpz:1:12

    Every tag cooks the same single-line escapes

    링크
    example.tpzEvery tag cooks the same single-line escapes플레이그라운드 열기 →
    1. import std.io
    2. let pattern = r"\n\r\t\\\"\{\}"
    3. io.writeLine(pattern.parts[0])
    4. let command = sh"\n\r\t\\\"\{\}"
    5. io.writeLine(command.parts[0])
    6. let query = sql"\n\r\t\\\"\{\}"
    7. io.writeLine(query.parts[0])
    기대 출력종료 코드 0
    
    
    	\"{}
    
    
    	\"{}
    
    
    	\"{}
    
    $ topaz run example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. \"{}
    2. \"{}
    3. \"{}

    The standard-output expectation checks the actual LF, CR, tab, backslash, quotation-mark, and brace characters in each cooked text part.

    Every tag cooks the same multiline escapes

    링크
    example.tpzEvery tag cooks the same multiline escapes플레이그라운드 열기 →
    1. import std.io
    2. let pattern = r"""
    3. \n\r\t\\\"\{\}
    4. """
    5. io.writeLine(pattern.parts[0])
    6. let command = sh"""
    7. \n\r\t\\\"\{\}
    8. """
    9. io.writeLine(command.parts[0])
    10. let query = sql"""
    11. \n\r\t\\\"\{\}
    12. """
    13. io.writeLine(query.parts[0])
    기대 출력종료 코드 0
    
    
    	\"{}
    
    
    
    	\"{}
    
    
    
    	\"{}
    
    
    $ topaz run example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. \"{}
    2. \"{}
    3. \"{}

    The standard-output expectation checks the actual LF, CR, tab, backslash, quotation-mark, and brace characters in each cooked text part.

    Unknown escape in a r template

    링크
    example.tpzUnknown escape in a r template플레이그라운드 열기 →
    1. let value = r"\d"
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 lex. 종료 코드가 0이 아닙니다.

    Use a supported escape or double the backslash to keep it as literal text.

    Unknown escape in a sh template

    링크
    example.tpzUnknown escape in a sh template플레이그라운드 열기 →
    1. let value = sh"\q"
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 lex. 종료 코드가 0이 아닙니다.

    Use a supported escape or double the backslash to keep it as literal text.

    Unknown escape in a sql template

    링크
    example.tpzUnknown escape in a sql template플레이그라운드 열기 →
    1. let value = sql"\q"
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 lex. 종료 코드가 0이 아닙니다.

    Use a supported escape or double the backslash to keep it as literal text.

    Preserve a regex backslash and literal braces

    링크
    example.tpzPreserve a regex backslash and literal braces플레이그라운드 열기 →
    1. import std.io
    2. let pattern = r"\\d+\{n\}"
    3. io.writeLine(pattern.parts[0])
    기대 출력종료 코드 0
    \d+{n}
    
    $ topaz run example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. \d+{n}

    Unknown escape in a multiline r template

    링크
    example.tpzUnknown escape in a multiline r template플레이그라운드 열기 →
    1. let pattern = r"""
    2. \d
    3. """
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 lex. 종료 코드가 0이 아닙니다.

    Reject uppercase hex prefix

    링크
    example.tpzReject uppercase hex prefix플레이그라운드 열기 →
    1. let value = 0Xff
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 parse. 종료 코드가 0이 아닙니다.

    • TPZ2001 →

      malformed-numeric-literal at example.tpz:1:13

    Reject uppercase binary prefix

    링크
    example.tpzReject uppercase binary prefix플레이그라운드 열기 →
    1. let value = 0B1010
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 parse. 종료 코드가 0이 아닙니다.

    • TPZ2001 →

      malformed-numeric-literal at example.tpz:1:13

    Reject uppercase hex digit

    링크
    example.tpzReject uppercase hex digit플레이그라운드 열기 →
    1. let value = 0xA
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 parse. 종료 코드가 0이 아닙니다.

    • TPZ2001 →

      malformed-numeric-literal at example.tpz:1:13

    Reject mixed case hex digit

    링크
    example.tpzReject mixed case hex digit플레이그라운드 열기 →
    1. let value = 0xaF
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 parse. 종료 코드가 0이 아닙니다.

    • TPZ2001 →

      malformed-numeric-literal at example.tpz:1:13

    Read lowercase radix literals

    링크
    example.tpzRead lowercase radix literals
    1. import std.io { writeLine }
    2. writeLine("{0xff}")
    3. writeLine("{0b1010}")
    4. writeLine("{0xabcdef}")
    기대 출력종료 코드 0
    255
    10
    11259375
    
    $ topaz run example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 255
    2. 10
    3. 11259375

    Reject physical LF in single-line text

    링크
    example.tpzReject physical LF in single-line text플레이그라운드 열기 →
    1. let value = "left
    2. right"
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 lex. 종료 코드가 0이 아닙니다.

    Reject physical LF in single-line interpolation

    링크
    example.tpzReject physical LF in single-line interpolation플레이그라운드 열기 →
    1. let value = "{1
    2. + 2}"
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 lex. 종료 코드가 0이 아닙니다.

    • TPZ0003 →

      single-line-interpolation-line-break at example.tpz:1:13

    Reject physical CRLF in single-line text

    링크
    example.tpzReject physical CRLF in single-line text플레이그라운드 열기 →
    1. let value = "left
    2. right"
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 lex. 종료 코드가 0이 아닙니다.

    Reject physical CRLF in single-line interpolation

    링크
    example.tpzReject physical CRLF in single-line interpolation플레이그라운드 열기 →
    1. let value = "{1
    2. + 2}"
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 lex. 종료 코드가 0이 아닙니다.

    • TPZ0003 →

      single-line-interpolation-line-break at example.tpz:1:13

    Reject physical CR in single-line text

    링크
    example.tpzReject physical CR in single-line text플레이그라운드 열기 →
    1. let value = "left right"
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 lex. 종료 코드가 0이 아닙니다.

    Reject physical CR in single-line interpolation

    링크
    example.tpzReject physical CR in single-line interpolation플레이그라운드 열기 →
    1. let value = "{1 + 2}"
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 lex. 종료 코드가 0이 아닙니다.

    • TPZ0003 →

      single-line-interpolation-line-break at example.tpz:1:13

    Reject physical CR in a string nested inside single-line interpolation

    링크
    example.tpzReject physical CR in a string nested inside single-line interpolation플레이그라운드 열기 →
    1. let value = "{""" inner"""}"
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 lex. 종료 코드가 0이 아닙니다.

    • TPZ0003 →

      single-line-interpolation-line-break at example.tpz:1:13

    Physical CRLF uses the same multiline text and indentation

    링크
    example.tpzPhysical CRLF uses the same multiline text and indentation플레이그라운드 열기 →
    1. import std.io
    2. let value = """
    3. first
    4. second
    5. """
    6. io.writeLine(value.encodeUtf8().toHex())
    기대 출력종료 코드 0
    66697273740a7365636f6e640a
    
    $ topaz run example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 66697273740a7365636f6e640a

    Physical CR uses the same multiline text and indentation

    링크
    example.tpzPhysical CR uses the same multiline text and indentation플레이그라운드 열기 →
    1. import std.io
    2. let value = """ first second """
    3. io.writeLine(value.encodeUtf8().toHex())
    기대 출력종료 코드 0
    66697273740a7365636f6e640a
    
    $ topaz run example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 66697273740a7365636f6e640a

    Reject missing indentation after a physical CR

    링크
    example.tpzReject missing indentation after a physical CR플레이그라운드 열기 →
    1. let value = """
    2. first second
    3. """
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 lex. 종료 코드가 0이 아닙니다.

    • TPZ0006 →

      multiline-closing-indent-mismatch at example.tpz:3:1

    Escaped carriage returns remain character data

    링크
    example.tpzEscaped carriage returns remain character data플레이그라운드 열기 →
    1. import std.io
    2. let opening = """\rhead"""
    3. let single = "S\rE"
    4. let multi = """
    5. M\rN
    6. """
    7. io.writeLine(opening.encodeUtf8().toHex())
    8. io.writeLine(single.encodeUtf8().toHex())
    9. io.writeLine(multi.encodeUtf8().toHex())
    기대 출력종료 코드 0
    0d68656164
    530d45
    4d0d4e0a
    
    $ topaz run example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 0d68656164
    2. 530d45
    3. 4d0d4e0a

    An inserted carriage return decoded from bytes remains character data

    링크
    example.tpzAn inserted carriage return decoded from bytes remains character data플레이그라운드 열기 →
    1. import std.io
    2. let data = match (Bytes.fromHex("0d")) {
    3. case Ok(bytes) => match (bytes.decodeUtf8()) {
    4. case Ok(value) => value
    5. case Err(_) => ""
    6. }
    7. case Err(_) => ""
    8. }
    9. let opening = """{data}head"""
    10. let single = "L{data}R"
    11. let multi = """
    12. L{data}R
    13. """
    14. io.writeLine(opening.encodeUtf8().toHex())
    15. io.writeLine(single.encodeUtf8().toHex())
    16. io.writeLine(multi.encodeUtf8().toHex())
    기대 출력종료 코드 0
    0d68656164
    4c0d52
    4c0d520a
    
    $ topaz run example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 0d68656164
    2. 4c0d52
    3. 4c0d520a

    Blank source lines ignore indentation

    링크
    example.tpzBlank source lines ignore indentation플레이그라운드 열기 →
    1. import std.io
    2. let indented = """
    3. A
    4. B
    5. """
    6. let unindented = """A
    7. B"""
    8. let tagged = r"""
    9. A
    10. B
    11. """
    12. io.writeLine(indented.encodeUtf8().toHex())
    13. io.writeLine(unindented.encodeUtf8().toHex())
    14. io.writeLine(tagged.parts[0].encodeUtf8().toHex())
    기대 출력종료 코드 0
    410a0a0a420a
    410a0a42
    410a0a420a
    
    $ topaz run example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 410a0a0a420a
    2. 410a0a42
    3. 410a0a420a

    Escaped and inserted whitespace remains data

    링크
    example.tpzEscaped and inserted whitespace remains data플레이그라운드 열기 →
    1. import std.io
    2. let inserted = " \t"
    3. let value = """
    4. A
    5. \t
    6. {inserted}
    7. B
    8. """
    9. io.writeLine(value.encodeUtf8().toHex())
    기대 출력종료 코드 0
    410a090a20090a420a
    
    $ topaz run example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 410a090a20090a420a

    Path construction uses Path.from instead of the p tag

    링크
    example.tpzPath construction uses Path.from instead of the p tag플레이그라운드 열기 →
    1. let value = p"notes"
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 parse. 종료 코드가 0이 아닙니다.

    Path construction uses Path.from instead of the p tag

    링크
    example.tpzPath construction uses Path.from instead of the p tag플레이그라운드 열기 →
    1. let value = p"""
    2. notes
    3. """
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 parse. 종료 코드가 0이 아닙니다.

    Path.from normalizes literal and interpolated text

    링크
    example.tpzPath.from normalizes literal and interpolated text플레이그라운드 열기 →
    1. import std.io
    2. import std.path { Path }
    3. function normalized(text: string) -> string {
    4. match (Path.from(text)) {
    5. case Ok(value) => value.toString()
    6. case Err(error) => error
    7. }
    8. }
    9. let directory = "notes"
    10. io.writeLine(normalized("./{directory}//draft/../chapter.tpz"))
    11. io.writeLine(normalized("notes\\draft\\..\\chapter.tpz"))
    12. io.writeLine(normalized("notes/.."))
    13. io.writeLine(normalized("Notes/가.TPZ"))
    기대 출력종료 코드 0
    notes/chapter.tpz
    notes/chapter.tpz
    .
    Notes/가.TPZ
    
    $ topaz run example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. notes/chapter.tpz
    2. notes/chapter.tpz
    3. .
    4. Notes/가.TPZ

    Invalid path text is an Err result

    링크
    example.tpzInvalid path text is an Err result플레이그라운드 열기 →
    1. import std.io
    2. import std.path { Path }
    3. function outcome(text: string) -> string {
    4. match (Path.from(text)) {
    5. case Ok(_) => "Ok"
    6. case Err(_) => "Err"
    7. }
    8. }
    9. io.writeLine("empty: {outcome("")}")
    10. io.writeLine("absolute: {outcome("/notes")}")
    11. io.writeLine("drive: {outcome("C:notes")}")
    12. io.writeLine("escape: {outcome("../notes")}")
    기대 출력종료 코드 0
    empty: Err
    absolute: Err
    drive: Err
    escape: Err
    
    $ topaz run example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. empty: Err
    2. absolute: Err
    3. drive: Err
    4. escape: Err

    Use Path.from instead of Path.cwdRelative

    링크
    example.tpzUse Path.from instead of Path.cwdRelative플레이그라운드 열기 →
    1. import std.path { Path }
    2. let value = Path.cwdRelative("notes")
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    Use Path.from instead of Path.project

    링크
    example.tpzUse Path.from instead of Path.project플레이그라운드 열기 →
    1. import std.path { Path }
    2. let value = Path.project("notes")
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    A Path is already normalized

    링크
    example.tpzA Path is already normalized플레이그라운드 열기 →
    1. import std.path { Path }
    2. function keep(value: Path) -> Path { value.normalize() }
    기대 출력0이 아닌 종료 코드
    $ topaz check example.tpz --compiler self --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    Use an existing Path directly

    링크
    example.tpzUse an existing Path directly플레이그라운드 열기 →
    1. import std.path { Path }
    2. function keep(value: Path) -> Path { value }
    기대 출력종료 코드 0
    표준 출력 없음.
    $ topaz check example.tpz --compiler self --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    Preserve composed, decomposed, and invisible string data

    링크
    example.tpzPreserve composed, decomposed, and invisible string data플레이그라운드 열기 →
    1. import std.io
    2. let composed = "é"
    3. let decomposed = "é"
    4. let hangul = "가"
    5. let invisible = "a͏‍️"
    6. let inserted = "{decomposed}"
    7. io.writeLine(composed.encodeUtf8().toHex())
    8. io.writeLine(decomposed.encodeUtf8().toHex())
    9. io.writeLine(hangul.encodeUtf8().toHex())
    10. io.writeLine(invisible.encodeUtf8().toHex())
    11. io.writeLine(inserted.encodeUtf8().toHex())
    기대 출력종료 코드 0
    c3a9
    65cc81
    e18480e185a1
    61cd8fe2808defb88f
    65cc81
    
    $ topaz run example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. c3a9
    2. 65cc81
    3. e18480e185a1
    4. 61cd8fe2808defb88f
    5. 65cc81

    Add and subtract Duration values

    링크
    example.tpzAdd and subtract Duration values
    1. import std.io { writeLine }
    2. let sum = 1s + 500ms
    3. let difference = 2s - 500ms
    4. writeLine("{sum}")
    5. writeLine("{difference}")
    기대 출력종료 코드 0
    1500ms
    1500ms
    
    $ topaz run example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 1500ms
    2. 1500ms

    Multiply a Duration by an int in either order

    링크
    example.tpzMultiply a Duration by an int in either order
    1. import std.io { writeLine }
    2. let count = 3
    3. let left = 500ms * count
    4. let right = count * 500ms
    5. let constructed = 1ms * count
    6. writeLine("{left}")
    7. writeLine("{right}")
    8. writeLine("{constructed}")
    기대 출력종료 코드 0
    1500ms
    1500ms
    3ms
    
    $ topaz run example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 1500ms
    2. 1500ms
    3. 3ms

    Compare Duration values by milliseconds

    링크
    example.tpzCompare Duration values by milliseconds
    1. import std.io { writeLine }
    2. let first = 1s
    3. let same = 1000ms
    4. let later = 2s
    5. writeLine("{Eq.equals(first, same)}")
    6. writeLine("{Order.compare(first, later) < 0}")
    7. writeLine("{first == same}")
    8. writeLine("{first != later}")
    9. writeLine("{first < later}")
    10. writeLine("{first <= same}")
    11. writeLine("{later > first}")
    12. writeLine("{same >= first}")
    기대 출력종료 코드 0
    true
    true
    true
    true
    true
    true
    true
    true
    
    $ topaz run example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. true
    2. true
    3. true
    4. true
    5. true
    6. true
    7. true
    8. true

    Display millisecond literals and extract int milliseconds

    링크
    example.tpzDisplay millisecond literals and extract int milliseconds
    1. import std.io { writeLine }
    2. let delay = 1500ms
    3. let minute = 1m
    4. let second = 1s
    5. let zero = 0ms
    6. let endpoint = 18446744073709551615ms
    7. let intEndpoint = 9223372036854775807ms
    8. writeLine(Show.show(delay))
    9. writeLine("{delay.toMillis()}")
    10. writeLine("{minute.toMillis()}")
    11. writeLine("{second.toMillis()}")
    12. writeLine("{zero}")
    13. writeLine("{endpoint}")
    14. writeLine("{intEndpoint.toMillis()}")
    기대 출력종료 코드 0
    1500ms
    1500
    60000
    1000
    0ms
    18446744073709551615ms
    9223372036854775807
    
    $ topaz run example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 1500ms
    2. 1500
    3. 60000
    4. 1000
    5. 0ms
    6. 18446744073709551615ms
    7. 9223372036854775807

    Reject a Duration subtraction below zero

    링크
    example.tpzReject a Duration subtraction below zero
    1. let earlier = 1ms
    2. let later = 2ms
    3. let difference = earlier - later
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz run example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 run. 종료 코드가 0이 아닙니다.

    • TPZ4004 →

      duration-negative-difference at example.tpz:3:18

    Reject a Duration sum outside its millisecond range

    링크
    example.tpzReject a Duration sum outside its millisecond range
    1. let largest = 18446744073709551615ms
    2. let result = largest + 1ms
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz run example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 run. 종료 코드가 0이 아닙니다.

    Reject a Duration product outside its millisecond range

    링크
    example.tpzReject a Duration product outside its millisecond range
    1. let large = 9223372036854775807ms
    2. let result = large * 3
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz run example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 run. 종료 코드가 0이 아닙니다.

    Reject multiplication by a negative int

    링크
    example.tpzReject multiplication by a negative int
    1. let delay = 1ms
    2. let count = -1
    3. let result = delay * count
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz run example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 run. 종료 코드가 0이 아닙니다.

    • TPZ4004 →

      duration-negative-multiplier at example.tpz:3:14

    Reject a millisecond count outside int

    링크
    example.tpzReject a millisecond count outside int
    1. let delay = 9223372036854775808ms
    2. let count = delay.toMillis()
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz run example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 run. 종료 코드가 0이 아닙니다.

    • TPZ4004 →

      duration-to-millis-overflow at example.tpz:2:13

    Pending contracts

    링크

    Related reference

    링크

    Lexical structure owns token boundaries and reserved spellings. General type compatibility belongs to Types; arithmetic and grouping belong to Expressions and operators. The enclosing timeout form belongs to Concurrency. Diagnostic entries own complete causes and remedies for each qualified diagnostic.

    Unexpected token →

    TPZ5001 →

    Invalid escape sequence →

    Unterminated string →

    Template indentation mismatch →

    Unknown template tag →

    Unknown member or field →

    Integer overflow →

    메뉴

    다운로드 →