// 08. 파서가 거부해야 하는 코드 // // 05와 목적이 다르다. 05는 구문은 맞지만 검사기가 거부해야 하는 파일이고, // 이 파일은 파서가 거부해야 하는 파일이다. // 파서는 항목 단위로 회복한다. 오류가 난 선언은 통째로 버리고 다음 선언에서 // 다시 시작하므로, 한 항목에 오류 하나가 상한이다. 이 파일은 항목마다 하나씩 // 심어 회복이 실제로 되는지 본다 — 아래 넷이 모두 보고되어야 한다. // [E-syntax-effect-union] 파라미터 위치의 합집합은 문법에 존재하지 않는다. // 검사기가 아니라 파서가 거부한다 (eff_param 프로덕션에 "|"가 없다). pub fn peel[a, e: effects]( f: fn(a) effects e | {Logger.write}, ) effects e -> fn(a) // ERROR (parse): 파라미터 위치의 effects 절은 변수 단독 또는 리터럴 집합만 허용 // [E-syntax-match-guard] match 가드는 v0 문법에 없다 pub fn classify(e: PayError) -> String { match e { Network(r) if r.retryable => "retry", // ERROR (parse): match 가드는 지원되지 않음. 분기 본문에서 if를 쓸 것 _ => "other", } } // [E-syntax-trailing-comma] 다중 줄 목록에는 후행 콤마가 필요하다. // 줄바꿈이 목록을 닫으려 하면 원인을 직접 말한다. pub fn missing_comma( a: Int, b: Int ) -> Int // ERROR (parse): 다중 줄 목록에는 후행 콤마가 필요합니다 // [E-syntax-scope-parent] 자식 scope는 부모를 명시해야 한다. // 부모 없는 작업이 생기지 않게 하는 것은 문법의 일이다. pub fn orphan(root: TaskScope) { scope sc { sc.spawn(fn() { }) } } // ERROR (parse): = (자식 scope의 부모를 명시해야 합니다) // 회복이 되었다는 증거: 이 마지막 선언은 정상적으로 읽혀야 한다. pub fn fine(n: Int) -> Int { n + 1 }