11 ECMAScript 언어: 소스 텍스트

11.1 소스 텍스트

구문

SourceCharacter :: 임의의 유니코드 코드 포인트

ECMAScript 소스 텍스트는 유니코드 코드 포인트들의 시퀀스이다. ECMAScript 문법이 허용하는 곳에서는, 서로게이트 코드 포인트를 포함하여 U+0000부터 U+10FFFF까지의 모든 유니코드 코드 포인트 값이 ECMAScript 소스 텍스트에 나타날 수 있다. ECMAScript 소스 텍스트를 저장하고 교환하는 데 사용되는 실제 인코딩은 이 명세와 관련이 없다. 외부 소스 텍스트 인코딩과 관계없이, 적합한 ECMAScript 구현은 소스 텍스트를 마치 동등한 SourceCharacter 값들의 시퀀스인 것처럼 처리하는데, 각 SourceCharacter는 하나의 유니코드 코드 포인트이다. 적합한 ECMAScript 구현은 소스 텍스트에 대해 어떤 정규화도 수행할 필요가 없으며, 마치 소스 텍스트 정규화를 수행하는 것처럼 동작할 필요도 없다.

결합 문자 시퀀스의 구성 요소들은, 사용자가 전체 시퀀스를 하나의 문자로 생각할 수 있더라도, 각각 개별 유니코드 코드 포인트로 취급된다.

Note

문자열 리터럴, 정규식 리터럴, 템플릿 리터럴, 식별자 안에서는, 임의의 유니코드 코드 포인트를 그 코드 포인트의 수치 값을 명시적으로 표현하는 유니코드 이스케이프 시퀀스를 사용해 나타낼 수도 있다. 주석 안에서 그러한 이스케이프 시퀀스는 사실상 주석의 일부로 무시된다.

ECMAScript는 유니코드 이스케이프 시퀀스의 동작에서 자바 프로그래밍 언어와 다르다. 예를 들어 자바 프로그램에서 유니코드 이스케이프 시퀀스 \u000A가 단일 행 주석 안에 나타나면, 그것은 줄 종결자(유니코드 코드 포인트 U+000A는 LINE FEED (LF)이다)로 해석되며, 따라서 다음 코드 포인트는 더 이상 주석의 일부가 아니다. 마찬가지로 자바 프로그램에서 유니코드 이스케이프 시퀀스 \u000A가 문자열 리터럴 안에 나타나면, 역시 줄 종결자로 해석되는데, 이는 문자열 리터럴 안에서는 허용되지 않는다—문자열 리터럴 값의 일부로 LINE FEED (LF)를 포함시키려면 \u000A 대신 \n을 써야 한다. ECMAScript 프로그램에서는 주석 안에 나타난 유니코드 이스케이프 시퀀스는 결코 해석되지 않으므로 주석의 종료에 기여할 수 없다. 마찬가지로 ECMAScript 프로그램에서 문자열 리터럴 안에 나타난 유니코드 이스케이프 시퀀스는 항상 그 리터럴의 일부에 기여하며, 결코 줄 종결자나 문자열 리터럴을 종료시킬 수 있는 코드 포인트로 해석되지 않는다.

11.1.1 Static Semantics: UTF16EncodeCodePoint ( cp )

The abstract operation UTF16EncodeCodePoint takes argument cp (a Unicode code point) and returns a String. It performs the following steps when called:

  1. Assert: 0 ≤ cp ≤ 0x10FFFF.
  2. cp ≤ 0xFFFF이면, 수치 값이 cp인 코드 단위로 이루어진 String 값을 반환한다.
  3. cu1을 수치 값이 floor((cp - 0x10000) / 0x400) + 0xD800인 코드 단위라고 하자.
  4. cu2를 수치 값이 ((cp - 0x10000) modulo 0x400) + 0xDC00인 코드 단위라고 하자.
  5. cu1cu2의 문자열 연결을 반환한다.

11.1.2 Static Semantics: CodePointsToString ( text )

The abstract operation CodePointsToString takes argument text (a sequence of Unicode code points) and returns a String. 이것은 6.1.4에 설명된 대로 text를 String 값으로 변환한다. It performs the following steps when called:

  1. result를 빈 String이라고 하자.
  2. text의 각 코드 포인트 cp에 대해, 다음을 수행한다
    1. resultresultUTF16EncodeCodePoint(cp)의 문자열 연결로 설정한다.
  3. result를 반환한다.

11.1.3 Static Semantics: UTF16SurrogatePairToCodePoint ( lead, trail )

The abstract operation UTF16SurrogatePairToCodePoint takes arguments lead (a code unit) and trail (a code unit) and returns a code point. UTF-16 서로게이트 쌍을 이루는 두 코드 단위는 하나의 코드 포인트로 변환된다. It performs the following steps when called:

  1. Assert: leadleading surrogate이고 trailtrailing surrogate이다.
  2. cp를 (lead - 0xD800) × 0x400 + (trail - 0xDC00) + 0x10000이라고 하자.
  3. 코드 포인트 cp를 반환한다.

11.1.4 Static Semantics: CodePointAt ( string, position )

The abstract operation CodePointAt takes arguments string (a String) and position (a non-negative integer) and returns a Record with fields [[CodePoint]] (a code point), [[CodeUnitCount]] (a positive integer), and [[IsUnpairedSurrogate]] (a Boolean). 이것은 6.1.4에 설명된 대로 string을 UTF-16으로 인코딩된 코드 포인트들의 시퀀스로 해석하고, 인덱스 position의 코드 단위에서 시작하는 하나의 코드 포인트를 읽는다. It performs the following steps when called:

  1. sizestring의 길이라고 하자.
  2. Assert: position ≥ 0 and position < size.
  3. firststring 안의 인덱스 position에 있는 코드 단위라고 하자.
  4. cp를 수치 값이 first의 수치 값인 코드 포인트라고 하자.
  5. firstleading surrogate도 아니고 trailing surrogate도 아니면,
    1. Record { [[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: false }를 반환한다.
  6. firsttrailing surrogate이거나 position + 1 = size이면,
    1. Record { [[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: true }를 반환한다.
  7. secondstring 안의 인덱스 position + 1에 있는 코드 단위라고 하자.
  8. secondtrailing surrogate가 아니면,
    1. Record { [[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: true }를 반환한다.
  9. cpUTF16SurrogatePairToCodePoint(first, second)로 설정한다.
  10. Record { [[CodePoint]]: cp, [[CodeUnitCount]]: 2, [[IsUnpairedSurrogate]]: false }를 반환한다.

11.1.5 Static Semantics: StringToCodePoints ( string )

The abstract operation StringToCodePoints takes argument string (a String) and returns a List of code points. 이것은 6.1.4에 설명된 대로 string을 UTF-16으로 인코딩된 유니코드 텍스트로 해석한 결과 얻어지는 유니코드 코드 포인트들의 시퀀스를 반환한다. It performs the following steps when called:

  1. codePoints를 새로운 빈 List라고 하자.
  2. sizestring의 길이라고 하자.
  3. position을 0이라고 하자.
  4. position < size인 동안, 다음을 반복한다
    1. cpCodePointAt(string, position)라고 하자.
    2. cp.[[CodePoint]]codePoints에 추가한다.
    3. positionposition + cp.[[CodeUnitCount]]로 설정한다.
  5. codePoints를 반환한다.

11.1.6 Static Semantics: ParseText ( sourceText, goalSymbol )

The abstract operation ParseText takes arguments sourceText (a String or a sequence of Unicode code points) and goalSymbol (a nonterminal in one of the ECMAScript grammars) and returns a Parse Node or a non-empty List of SyntaxError objects. It performs the following steps when called:

  1. sourceText가 String이면, sourceTextStringToCodePoints(sourceText)로 설정한다.
  2. goalSymbol을 goal symbol로 사용하여 sourceText를 파싱하려 시도하고, 파싱 결과를 early error 조건에 대해 분석한다. 파싱과 early error 검출은 구현 정의된 방식으로 상호 교차되어 수행될 수 있다.
  3. 파싱이 성공하고 early error가 발견되지 않았다면, 파싱 결과로 생성된 파스 트리의 루트에 있는 Parse Node(goalSymbol의 인스턴스)를 반환한다.
  4. 파싱 오류 및/또는 early error를 나타내는 하나 이상의 SyntaxError 객체의 List를 반환한다. 둘 이상의 파싱 오류 또는 early error가 존재하는 경우, 리스트 안의 오류 객체의 개수와 순서는 구현 정의이지만, 최소 하나는 반드시 존재해야 한다.
Note 1

특정 지점에 early error가 있고, 더 뒤의 지점에 syntax error도 있는 텍스트를 생각해 보자. 먼저 파싱 패스를 수행한 다음 early errors 패스를 수행하는 구현은 syntax error를 보고하고 early errors 패스로 진행하지 않을 수 있다. 두 작업을 상호 교차하여 수행하는 구현은 early error를 보고하고 syntax error를 찾으러 진행하지 않을 수 있다. 세 번째 구현은 두 오류를 모두 보고할 수도 있다. 이 모든 동작은 적합하다.

Note 2

17 절도 보라.

11.2 소스 코드의 종류

ECMAScript 코드에는 네 가지 종류가 있다:

Note 1

함수 코드는 일반적으로 함수 정의(15.2), 화살표 함수 정의(15.3), 메서드 정의(15.4), 제너레이터 함수 정의(15.5), 비동기 함수 정의(15.8), 비동기 제너레이터 함수 정의(15.6), 비동기 화살표 함수(15.9)의 본문으로 제공된다. 함수 코드는 또한 Function 생성자(20.2.1.1), GeneratorFunction 생성자(27.3.1.1), AsyncFunction 생성자(27.7.1.1), AsyncGeneratorFunction 생성자(27.4.1.1)에 대한 인수로부터도 파생된다.

Note 2

BindingIdentifier를 함수 코드에 포함시키는 실질적인 효과는, 둘러싼 코드가 strict mode 코드가 아니더라도, 본문 안에 "use strict" 지시어를 포함하는 함수의 이름인 BindingIdentifier에 대해 strict mode 코드의 Early Error가 적용된다는 점이다.

11.2.1 지시어 프롤로그와 Use Strict 지시어

지시어 프롤로그FunctionBody, ScriptBody, 또는 ModuleBody의 처음 StatementListItem들이나 ModuleItem들로 나타나는 ExpressionStatement들의 가장 긴 시퀀스이며, 그 시퀀스의 각 ExpressionStatement는 전적으로 StringLiteral 토큰 뒤에 세미콜론이 오는 형태로 이루어진다. 세미콜론은 명시적으로 나타날 수도 있고 자동 세미콜론 삽입(12.10)에 의해 삽입될 수도 있다. 지시어 프롤로그는 빈 시퀀스일 수도 있다.

Use Strict 지시어지시어 프롤로그 안의 ExpressionStatement로서, 그 StringLiteral이 정확한 코드 포인트 시퀀스 "use strict" 또는 'use strict' 중 하나인 것이다. Use Strict 지시어EscapeSequenceLineContinuation을 포함할 수 없다.

지시어 프롤로그는 하나 이상의 Use Strict 지시어를 포함할 수 있다. 그러나 이 경우 구현은 경고를 낼 수 있다.

Note

지시어 프롤로그ExpressionStatement들은 그것을 포함하는 production의 평가 중에 정상적으로 평가된다. 구현은 Use Strict 지시어가 아니면서 지시어 프롤로그 안에 나타나는 ExpressionStatement에 대해 구현 특화 의미를 정의할 수 있다. 적절한 알림 메커니즘이 존재한다면, 구현은 Use Strict 지시어가 아니고 구현에 의해 정의된 의미도 가지지 않는 ExpressionStatement지시어 프롤로그 안에서 만나면 경고를 내야 한다.

11.2.2 Strict Mode 코드

ECMAScript 구문 단위는 unrestricted 또는 strict mode 구문 및 의미론(4.3.2)을 사용하여 처리될 수 있다. 코드는 다음 상황에서 strict mode 코드로 해석된다:

strict mode 코드가 아닌 ECMAScript 코드는 non-strict 코드라고 한다.

11.2.2.1 Static Semantics: IsStrict ( node )

The abstract operation IsStrict takes argument node (a Parse Node) and returns a Boolean. It performs the following steps when called:

  1. node에 매칭되는 소스 텍스트가 strict mode 코드이면, true를 반환한다.
  2. false를 반환한다.

11.2.3 비-ECMAScript 함수

ECMAScript 구현은 평가 동작이 ECMAScript 소스 텍스트가 아닌 어떤 호스트 정의 실행 코드 형식으로 표현되는 함수 이색 객체의 평가를 지원할 수 있다. 함수 객체가 ECMAScript 코드 안에서 정의되었는지, 또는 내장 함수인지는, 그러한 함수 객체를 호출하거나 그러한 함수 객체에 의해 호출되는 ECMAScript 코드의 관점에서는 관찰 가능하지 않다.