하자 Haja

1. 언어 개요 및 문법

하자(Haja) 언어의 기술 명세 요약본입니다.

기술 상세 명세 (Technical Specification)

이 부분은 파서(Parser) 및 런타임 구현자를 위한 엄격한 규칙 정의예요.

1. 어휘 및 구문 규칙 (Lexical & Syntax)

  • 식별자(Identifiers): 모든 변수명, 속성명, 특수 예약어 '나'(self)는 반드시 작은따옴표 ''로 감싸야 해요. 문자열 "" 내부에 쓰인 '는 무시되고 텍스트로 취급돼요.
  • 타입 어노테이션: 타입은 반드시 대괄호 []로 명시해야 해요. 렉서는 [ 기호 뒤에 이름이 오면 타입으로([숫자]), 값이 오면 목록으로(["사과"]) 명확히 구분하여 파싱해요. 단, 빈 목록 []을 생성할 때는 파서의 모호성을 없애기 위해 반드시 '빈배열'을 [목록]인 []로 정하자처럼 타입을 명시해야 해요.
  • 블록 정의: 콜론(:)과 **들여쓰기(Indentation)**로 코드 블록을 구분해요. 줄바꿈이 문장의 종료를 의미해요.
  • 논리 연산자: 그리고또는이 섞인 복잡한 조건식은 모호성을 피하기 위해 반드시 소괄호 ()를 사용하여 우선순위를 강제해야 해요.

2. 타입과 객체지향 규약 (Types & OOP)

  • 점진적 타이핑(Gradual Typing): 교육용 언어라는 철학에 맞추어 타입 어노테이션([타입]인, [타입]을 돌려주는 등)은 완벽히 생략 가능해요. 타입을 생략하면 파서는 이를 동적 타입([아무거나])으로 취급하여 유연하게 동작하며, 명시적으로 타입을 적어주면 실행(평가) 시점에 엄격하게 검사하는 정적 타입 모드로 동작해요.
  • 접근 제어(Access Modifiers): 숨기자(Private), 물려주자(Protected), 정하자/만들자(Public) 동사로 캡슐화를 강제해요. 숨기자로 선언된 속성은 자식 클래스 인스턴스 메모리 내부에는 존재하지만, 자식 스코프에서는 절대 접근할 수 없어요 (완전한 은닉).
  • 단일 상속과 인터페이스: 다이아몬드 상속 문제를 방지하기 위해 클래스는 단일 상속만 지원해요. 다중 구현(다형성)이 필요할 때는 인터페이스를 사용해요. 인터페이스(규약 선언)는 따른다 키워드로 상속받아요. 클래스 선언부에서 [인터페이스]를 따른다고 선언한 뒤, 해당 필수 메서드를 다 구현했는지의 여부는 클래스 선언문이 평가되는 시점(런타임)에 즉시 검사되어 오류로 처리돼요.
  • 상속 시 생성자: 자식 클래스에서 생성자를 생략하면 부모의 생성자가 자동 호출돼요. 덮어쓸 경우 부모의 <처음 만들어질 때>()를 실행하자로 명시적 호출이 가능해요.

3. 함수와 변수 스코프 (Functions & Scope)

  • 어휘적 스코프와 클로저(Closure): 하자 언어는 어휘적 스코프(Lexical Scoping) 기반의 클로저를 지원해요. 바깥의 키워드를 사용하면 부모 환경(Scope) 체인을 타고 올라가며 상위 스코프의 변수를 탐색하고 조작할 수 있어요.
  • 일급 객체 함수 (First-class Function): 함수 자체는 일급 값으로 취급돼요. 즉, '비교함수'를 <크다>로 정하자처럼 변수에 함수를 담아 콜백으로 전달하는 패턴을 정상적으로 지원해요.
  • 반환값(Return): 함수에서 명시적으로 돌려주자를 호출하지 않으면, 기본적으로 비어있음을 반환해요.

4. 타입 시스템 및 호환성 상세 (Type System & Compatibility)

  • [아무거나] 타입: 타입을 생략한 변수나 매개변수는 내부적으로 [아무거나](Any) 타입으로 취급되며, 타입 검사기가 일체의 런타임 제약을 무시하고 무조건 통과시켜요.
  • Nullable 기본 허용: '변수'를 [타입]으로 준비하자로 선언만 할 경우 메모리에 비어있음(Null)이 할당돼요. 즉, 모든 타입은 기본적으로 비어있음을 허용해요.
  • 재대입 (Reassignment): 이미 선언된 변수에 값을 변경할 때는 타입을 명시하지 않아요. 단, 초기 선언 시 정해진 타입과 다른 타입의 값을 재대입하거나 연산하려 하면 런타임 에러(TypeError)가 발생해요.
  • 묵시적 형변환 금지: 10 + "안녕"과 같은 묵시적(Implicit) 형변환은 엄격히 금지돼요. 반드시 <숫자로>(), <문자로>() 내장 도구를 통해 명시적으로 변환해야 해요.
  • 업캐스팅 (Upcasting): 부모 타입으로 선언된 변수에 자식 객체를 할당하거나, 인터페이스 타입 매개변수에 이를 따르는(구현한) 객체를 전달하는 것은 런타임에 안전한 호환으로 통과돼요.
  • 제네릭(Generics): 현재 [배열]이나 [사전] 타입 지정 시 내부 타입을 특정하지 않는 동적 컬렉션(타입 시스템상 [아무거나] 취급)을 사용해요. 제네릭 지원 여부 및 문법 등은 현재 **미정(TBD)**이에요.

5. 모듈 및 예외 (Modules & Exceptions)

  • 도구(모듈) 가져오기 규칙: 사용자 정의 파일은 문자열("파일이름")로, 빌트인 모듈은 대괄호([모듈명])로 가져와 이름 충돌을 방지해요. "수학"수학.haja를 임포트하지만, [수학]은 언어 인터프리터가 기본적으로 제공하는 내장 수학 도구를 임포트해요. 전체를 가져오려면 "수학"에서 전부 가져오자를, 특정 항목만 가져오려면 [수학]에서 <반올림>과 '파이'를 가져오자 처럼 사용해요.
  • 순환 임포트(Circular Import): 실행 시점에 모듈 캐싱을 통해 무한 루프를 방지해요.
  • 예외 객체 구조: 발생된 에러 객체는 내장된 [오류] 클래스의 인스턴스이며, 기본적으로 '메시지' 속성을 가져요.

놀이터 (Playground)

터미널
코드를 작성하고 '실행' 버튼을 눌러보세요.