KingSejong 언어 사용자 가이드
문서 목적: 언어 기능 레퍼런스 및 도구 사용법 (빠른 참조용) 대상 독자: KingSejong 언어의 특정 기능을 찾아보려는 개발자 이 문서의 코드는 모두 현재 인터프리터로 실행해 확인한 것이다. 변경 이력은 CHANGELOG 를 본다.
💡 문서 선택 가이드:
📚 목차
빠른 시작
설치
# 저장소 클론
git clone https://github.com/kingsejong-lang/kingsejong-lang.git
cd kingsejong-lang
# 빌드 (C++23 컴파일러와 CMake 3.20 이상)
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j8
# 설치 (선택: 실행 파일과 stdlib 를 시스템 경로에 둔다)
sudo cmake --install build플랫폼별 자세한 절차는 설치 가이드 를 본다. 설치하지 않고 쓰려면 build/bin/kingsejong 을 그대로 실행한다.
첫 프로그램 작성
hello.ksj 파일을 생성하세요:
# 간단한 인사 프로그램
출력("안녕하세요, KingSejong!")
정수 나이 = 25
문자열 이름 = "세종"
출력(이름 + "님의 나이는 " + 문자열(나이) + "살입니다")문자열과 숫자를 + 로 이으려면 문자열(값) 으로 먼저 바꾼다.
실행
kingsejong hello.ksj출력:
안녕하세요, KingSejong!
세종님의 나이는 25살입니다kingsejong --vm hello.ksj 는 같은 프로그램을 바이트코드 VM 으로 실행한다. 결과는 같고, 함수 호출이 많은 코드에서 빠르다.
개발 환경 설정
VS Code 확장 설치
확장은 아직 마켓플레이스에 올라가 있지 않아 저장소의 vscode-extension/ 디렉토리에서 직접 띄운다. 언어 서버는 kingsejong --lsp 다.
cmake -S . -B build && cmake --build build -j8 # 언어 서버(kingsejong 실행 파일) 빌드
cd vscode-extension
npm install
npm run bundleVS Code 에서 vscode-extension 디렉토리를 열고 F5 를 누르면 확장이 켜진 창이 뜬다. 그 창에서 .ksj 파일을 연다.
제공 기능:
- 구문 강조
- 자동 완성 (키워드, 변수, 함수 매개변수 힌트)
- 정의 이동 (F12), 참조 찾기, 이름 바꾸기
- 호버 정보
- 오류 진단 (구문·의미 오류 밑줄)
- 코드 포맷팅 (Shift+Alt+F,
kingsejong fmt를 부른다)
REPL 모드
대화형으로 코드를 실행하려면 파일 없이 실행한다:
kingsejongKingSejong v0.5.0
대화형 실행 환경 (REPL)
도움말: .help 또는 .도움말, 종료: .exit 또는 Ctrl+D
>>> 정수 x = 10
>>> 정수 y = 20
>>> 출력(x + y)
30REPL 명령어는 점으로 시작한다: .help(도움말), .vars(정의된 변수 목록), .clear(변수 초기화), .exit(종료). Ctrl+D 로도 끝낸다.
주요 기능 가이드
1. 한글 조사 체인 (독창적 문법)
KingSejong의 가장 독특한 기능입니다. 배열 뒤에 조사(을/를)를 붙이고 메서드를 쓴다:
배열 숫자들 = [1, 2, 3, 4, 5]
# 조사 메서드: 걸러낸다(filter), 변환한다(map), 정렬한다, 역순으로_나열한다, 축약한다(reduce), 찾다(find)
큰수들 = 숫자들을 걸러낸다(함수(x) { 반환 x > 2 })
결과 = 큰수들을 변환한다(함수(x) { 반환 x * 2 })
출력(결과) # [6, 8, 10]한 식에서 이어 쓸 수도 있다. 조사는 바로 앞 단계의 결과에 붙는다:
배열 숫자들 = [1, 2, 3, 4, 5]
결과 = 숫자들을 걸러낸다(함수(x) { 반환 x > 2 })를 변환한다(함수(x) { 반환 x * 2 })
출력(결과) # [6, 8, 10]조사는 받침에 따라 자동으로 맞춰진다 (숫자들을, 결과를). 자세한 규칙은 언어 레퍼런스 를 본다.
2. 클래스와 객체 지향
필드는 비공개/공개 와 타입을 붙여 선언하고, 메서드는 공개 함수, 자기 자신은 자신 으로 가리킨다. 자신 과 상위 는 메서드·생성자 안(그 안의 함수 포함)에서만 쓸 수 있고, 밖에서 쓰면 실행 전에 의미 오류가 난다. 인스턴스는 클래스 이름을 함수처럼 불러 만든다.
클래스 사람 {
비공개 문자열 이름
비공개 정수 나이
생성자(이름, 나이) {
자신.이름 = 이름
자신.나이 = 나이
}
공개 함수 인사하다() {
출력("안녕하세요, 저는 " + 자신.이름 + "입니다")
}
공개 함수 나이먹다() {
자신.나이 = 자신.나이 + 1
}
공개 함수 나이() {
반환 자신.나이
}
}
철수 = 사람("철수", 25)
철수.인사하다() # 안녕하세요, 저는 철수입니다
철수.나이먹다()
출력(철수.나이()) # 26생성자에서 대입하는 필드는 미리 선언돼 있어야 한다. 선언하지 않은 필드에 대입하면 필드 'x'이(가) 존재하지 않습니다 실행 오류가 난다.
클래스 자식 상속 부모 로 상속한다. 자식은 부모의 필드·메서드·생성자를 물려받고, 같은 이름의 메서드를 정의하면 자식 것이 쓰인다. 부모 메서드 안의 자신.메서드() 도 자식의 메서드를 부른다. 메서드·생성자 안에서 상위.메서드(...) 는 그 메서드를 정의한 클래스의 부모 메서드를, 상위(...) 는 부모 생성자를 같은 인스턴스에 대해 부른다.
클래스 동물 {
공개 문자열 이름
생성자(이름) {
자신.이름 = 이름
}
공개 함수 소개() {
반환 자신.이름 + ": " + 자신.소리()
}
공개 함수 소리() {
반환 "..."
}
}
클래스 개 상속 동물 {
공개 함수 소리() {
반환 "멍멍"
}
}
출력(개("바둑이").소개()) # 바둑이: 멍멍클래스 동물 {
공개 문자열 이름
생성자(이름) {
자신.이름 = 이름
}
공개 함수 소리() {
반환 "..."
}
}
클래스 개 상속 동물 {
공개 정수 나이
생성자(이름, 나이) {
상위(이름)
자신.나이 = 나이
}
공개 함수 소리() {
반환 "멍멍 (원래 " + 상위.소리() + ")"
}
}
바둑이 = 개("바둑이", 3)
출력(바둑이.이름, 바둑이.소리()) # 바둑이 멍멍 (원래 ...)3. 비동기 프로그래밍 (비동기 함수 / 대기)
비동기 함수 는 호출하면 Promise 를 돌려주고, 대기 는 Promise 가 끝날 때까지 기다려 값을 꺼낸다. 비동기 함수는 이름 = 비동기 함수() {} 로 대입하거나 비동기 함수 이름() {} 로 선언한다.
두배 = 비동기 함수(값) {
반환 값 * 2
}
메인 = 비동기 함수() {
데이터 = 대기 두배(21)
출력(데이터)
}
대기 메인() # 42비동기 함수 안에서 던지다 로 던진 에러는 그 Promise 의 거부가 되고, 거부된 Promise 를 대기 하면 그 에러가 다시 던져진다. 시도 블록으로 잡을 수 있다. 콜백 방식(그러면/오류시)은 언어 레퍼런스 를 본다.
4. 예외 처리
시도 / 오류 (변수) / 마지막 과 던지다 를 쓴다. 오류 블록의 변수에는 에러 메시지가 문자열로 들어온다.
시도 {
정수 결과 = 10 / 0
} 오류 (e) {
출력("에러 발생: " + e)
} 마지막 {
출력("정리 작업 수행")
}출력:
에러 발생: RuntimeError: 0으로 나눌 수 없습니다.
해결 방법: 나누는 값이 0이 아닌지 확인하세요. 조건문을 사용하여 검사할 수 있습니다.
정리 작업 수행직접 던지려면 던지다 "메시지" 를 쓴다. 아무도 잡지 않은 에러는 오류 위치·소스 문맥·호출 스택과 함께 보고되고 프로그램이 종료 코드 1 로 끝난다.
5. 패턴 매칭
값 에 대해 { 패턴 -> 결과 } 형태다. 식으로 쓰이므로 결과를 바로 반환하거나 대입할 수 있다. when 으로 가드를 붙이고, _ 는 무엇이든 맞는다.
함수 처리하다(값) {
반환 값 에 대해 {
0 -> "영"
1 -> "일"
n when n > 1 -> "둘 이상"
_ -> "기타"
}
}
출력(처리하다(1)) # 일
출력(처리하다(7)) # 둘 이상
출력(처리하다(-1)) # 기타맞는 패턴이 하나도 없으면 매칭되는 패턴이 없습니다 실행 오류가 난다.
6. 모듈 시스템
모듈은 그냥 .ksj 파일이다. 파일의 최상위에서 정의한 함수·변수가 모두 가져온 쪽에 들어오므로 내보내기 선언은 없다. 경로는 확장자 없이, 가져오는 파일을 기준으로 적는다.
lib/math_utils.ksj:
함수 제곱(x) {
반환 x * x
}
함수 세제곱(x) {
반환 x * x * x
}main.ksj:
가져오기 "lib/math_utils"
출력(제곱(5)) # 25
출력(세제곱(3)) # 27표준 라이브러리는 가져오기 "stdlib/math" 처럼 가져온다. 모듈을 찾는 순서는 가져오는 파일의 디렉토리, 현재 디렉토리, 환경 변수 KINGSEJONG_PATH 에 적은 디렉토리다 (./, ../ 로 시작하면 앞의 둘만 본다). 같은 모듈을 여러 번 가져와도 한 번만 실행되고, 순환 가져오기는 오류다.
도구 사용법
1. Linter
코드 품질을 검사합니다. 서브커맨드 lint 를 쓴다:
kingsejong lint myfile.ksjmyfile.ksj:3:9: 경고 [no-self-comparison]: 변수를 자기 자신과 비교하고 있습니다 (항상 같은 결과)
myfile.ksj:2:1: 경고 [unused-variable]: 변수 '사용안함'이 선언되었지만 사용되지 않습니다
검사 완료: 파일 1개, 오류 0개, 경고 2개규칙은 12개다: 미사용 변수·매개변수, 도달 불가능한 코드, 자기 비교, 상수 조건, 빈 블록, 매직 넘버, 변수 가리기, 이름 규칙, 줄 길이, 줄 끝 공백, 상수 선호. 규칙별 설명과 끄는 방법(.ksjlint.json)은 Linter 규칙 과 설정 파일 가이드 를 본다.
2. Formatter
코드를 자동으로 포맷팅합니다. 파일을 제자리에서 고쳐 쓴다:
kingsejong fmt myfile.ksj
kingsejong fmt --config .ksjfmt.json myfile.ksj주석(#, //)과 문장 사이의 빈 줄(하나까지), 작성자가 넣은 괄호, 여러 줄로 쓴 배열·사전, 한 줄로 쓴 짧은 블록, 같은 뜻의 여러 표기(만약 조건의 괄호 유무, 반복/동안, 까지/이하/이상, 범위 반복문 끝의 반복·반복한다)는 그대로 둔다. 파일에 쓰기 전에 결과를 다시 파싱해 원본과 구문 트리·주석이 같은지 확인하고, 다르면 파일을 고치지 않고 에러로 끝난다.
설정 파일 (.ksjfmt.json):
{
"indentSize": 4,
"useSpaces": true,
"spaceAroundOperators": true,
"spaceAfterComma": true,
"spaceBeforeBrace": true,
"maxLineLength": 100
}3. 디버거
중단점을 설정하고 단계별로 실행합니다:
kingsejong --debug myfile.ksj프로그램은 파싱만 된 상태로 멈춰 있다. break 파일:줄 로 중단점을 건 뒤 run 으로 시작한다. 중단점의 파일 이름은 명령행에 적은 경로와 같아야 한다.
KingSejong 디버거. 중단점: break myfile.ksj:<줄>, 시작: run, 도움말: help
(ksj-debug) break myfile.ksj:5
(ksj-debug) run디버거 명령어 (괄호는 줄임말):
break 파일:줄(b) - 중단점 설정,delete로 삭제,list로 목록run(r) - 실행 시작step(s) - 한 줄 실행 (함수 안으로)next(n) - 다음 줄 실행 (함수 건너뛰기)continue(c) - 다음 중단점까지 실행print 변수(p) - 변수 값 출력backtrace(bt) - 호출 스택 출력watch 변수(w) - 와치포인트 설정quit(q) - 종료
자세한 사용법은 디버거 가이드 를 본다.
4. 샌드박스 실행
신뢰할 수 없는 스크립트는 파일 접근을 제한해 실행할 수 있다:
kingsejong --sandbox myfile.ksj # 현재 디렉토리만 접근 허용
kingsejong --sandbox --allow-path /data myfile.ksj # 경로 추가 허용
kingsejong --untrusted myfile.ksj # 시스템 경로(/etc, /sys, /proc ...) 차단표준 라이브러리
파일·JSON·시간·정규표현식·암호화·HTTP 의 핵심 함수는 C++ 내장 함수라 가져오기 없이 바로 쓴다. stdlib/*.ksj 는 그 위의 편의 함수 모음이며 가져오기 "stdlib/모듈" 로 가져온다. 전체 목록은 표준 라이브러리 레퍼런스 와 각 stdlib/*.ksj 파일 머리의 주석을 본다.
파일 입출력 (내장)
# 파일 쓰기와 읽기
파일_쓰기("test.txt", "Hello, World!")
내용 = 파일_읽기("test.txt")
출력(내용) # Hello, World!
# 존재 확인과 삭제
출력(파일_존재("test.txt")) # 참
파일_삭제("test.txt")
출력(파일_존재("test.txt")) # 거짓사용자 입력은 입력("프롬프트") 로 받는다. 프롬프트를 출력하고 한 줄을 문자열로 돌려준다.
이름 = 입력("이름을 입력하세요: ")
출력("안녕하세요, " + 이름 + "님!")그 밖에 파일_추가, 줄별_읽기, 파일_복사, 파일_이동, 디렉토리_생성, 디렉토리_목록, 현재_디렉토리 가 있다.
JSON (내장 + stdlib/json)
JSON_파싱 은 JSON 객체를 [["키", 값], ...] 형태의 쌍 배열로 돌려준다. 값을 꺼내고 넣는 편의 함수는 stdlib/json 에 있다.
가져오기 "stdlib/json"
데이터 = JSON_파싱("{\"이름\": \"세종\", \"나이\": 25}")
출력(JSON_가져오기(데이터, "이름")) # 세종
출력(JSON_가져오기(데이터, "나이")) # 25
데이터2 = JSON_추가(데이터, "도시", "서울")
출력(JSON_문자열화(데이터2)) # {"나이":25,"도시":"서울","이름":"세종"}JSON_문자열화(값, 2) 는 들여쓰기한 문자열을, JSON_파일_읽기/JSON_파일_쓰기 는 파일을 바로 다룬다.
시간 (내장 + stdlib/time)
가져오기 "stdlib/time"
지금 = 현재_시간() # Unix 타임스탬프 (초, 정수)
출력(시간_포맷(지금, "%Y-%m-%d %H:%M:%S")) # 2026-10-25 06:46:50
출력(현재_날짜()) # 2026-10-25
내일 = 날짜_더하기(지금, 1)
출력(시간_포맷(내일, "%Y-%m-%d")) # 2026-10-26시간_포맷 의 형식은 C 의 strftime 과 같다. 현재_시각() 은 HH:MM:SS 문자열, 현재_날짜시간() 은 날짜와 시각을 함께 돌려준다.
정규표현식 (내장)
인자 순서는 (대상 문자열, 패턴) 이다.
출력(정규표현식_일치("hello@example.com", "^[a-z]+@[a-z]+\\.com$")) # 참 (전체 일치)
출력(정규표현식_검색("abc123def", "[0-9]+")) # 참 (부분 일치)
출력(정규표현식_추출("abc123def", "[0-9]+")) # 123
출력(이메일_검증("user@domain.com")) # 참그 밖에 정규표현식_모두_찾기, 정규표현식_치환, 정규표현식_분리, 정규표현식_개수, URL_검증, 전화번호_검증 이 있다.
암호화 (내장 + stdlib/crypto)
가져오기 "stdlib/crypto"
출력(Base64_인코딩("Hello")) # SGVsbG8=
출력(문자열_해시("비밀번호")) # 16진수 해시 문자열
# 소금을 붙인 비밀번호 해시와 검증
소금 = 랜덤_문자열(16)
저장할_해시 = 비밀번호_해시("my_password", 소금)
출력(비밀번호_검증("my_password", 소금, 저장할_해시)) # 참
출력(비밀번호_검증("wrong", 소금, 저장할_해시)) # 거짓내장 문자열_해시 는 암호학적 해시(SHA-256 등)가 아니라 C++ std::hash 기반이다. 실제 인증 시스템의 비밀번호 저장에는 쓰지 않는다.
HTTP (내장 + stdlib/http)
가져오기 "stdlib/http"
응답 = HTTP_GET("https://api.github.com")
출력(응답_상태(응답)) # 200
출력(응답_본문(응답)) # 응답 본문 문자열
결과 = HTTP_POST("https://api.example.com", "{\"name\": \"세종\"}")HTTP_요청(메서드, URL, 헤더, 본문) 으로 임의의 요청을 보낸다. 응답은 [["상태", 코드], ["본문", 내용], ["헤더", 헤더들]] 형태의 쌍 배열이고, 응답_상태/응답_본문/성공인가 가 그 안에서 값을 꺼낸다.
디버깅 & 문제 해결
일반적인 오류
1. "정의되지 않은 식별자"
선언하지 않은 이름을 쓰면 실행 전에 의미 분석 단계에서 잡힌다:
# 잘못된 코드
출력(x) # Semantic Error: 1:8: 정의되지 않은 식별자: x
# 올바른 코드
정수 x = 10
출력(x)2. "타입 불일치"
타입을 붙여 선언한 변수에는 그 타입의 값만 넣을 수 있다. 타입 없이 대입으로 만든 변수는 동적이다:
# 잘못된 코드
정수 x = 10
x = "문자열" # Semantic Error: 타입 불일치: 정수 변수 'x'에 문자열 값을 할당할 수 없습니다
# 올바른 코드
y = 10
y = "문자열" # OK: 타입 없이 만든 변수는 동적3. "모듈을 찾을 수 없습니다"
가져오기 "stdlib/io" # 저장소의 stdlib/ 디렉토리 (현재 디렉토리 또는 KINGSEJONG_PATH 에서 찾는다)
가져오기 "lib/math_utils" # 가져오는 파일을 기준으로 한 상대 경로, 확장자 없이설치하지 않고 저장소 밖에서 실행할 때는 KINGSEJONG_PATH 에 저장소 경로를 넣는다: export KINGSEJONG_PATH=/path/to/kingsejong-lang.
4. 실행 오류 읽는 법
잡히지 않은 실행 오류는 위치, 소스 문맥, 메시지, 그리고 함수 안에서 났다면 호출 스택을 함께 보여 준다:
📍 오류 위치: calc.ksj:2:8
1 | 함수 나누기(a, b) {
2 | 반환 a / b
^
3 | }
❌ 0으로 나누기 오류: 0으로 나눌 수 없습니다.
호출 스택 (가장 안쪽부터):
나누기 (calc.ksj:2)
계산 (calc.ksj:5)
<최상위> (calc.ksj:7)파일:줄:열 의 열은 한글도 한 글자로 세므로 편집기의 열 표시와 같다.
성능 최적화 팁
반복문 안에서 변하지 않는 값은 밖에서 한 번 계산한다
ksj배열 자료 = [3, 1, 4, 1, 5, 9, 2, 6] # 느림: 조건을 평가할 때마다 길이를 다시 구한다 정수 i = 0 반복 (i < 길이(자료)) { i = i + 1 } # 빠름: 한 번만 구한다 정수 n = 길이(자료) i = 0 반복 (i < n) { i = i + 1 }함수 호출이 많은 코드는
--vm으로 실행한다바이트코드 VM 은 평가기와 같은 결과를 내면서 재귀·호출이 많은 코드에서 훨씬 빠르다 (피보나치 25 기준 약 20배).
큰 자료는 다 쓰고 나면 놓는다
ksj배열 큰데이터 = [1, 2, 3] # ... 사용 ... 큰데이터 = 없음 # 더 참조하지 않으면 메모리가 해제된다
모범 사례
1. 네이밍 컨벤션
# 변수: 한글 또는 snake_case
정수 사용자_나이 = 25
# 함수: 동사형 한글 이름
함수 계산_합계(a, b) {
반환 a + b
}
# 클래스: 명사형 한글 이름
클래스 사용자계정 {
비공개 문자열 아이디
}
# 상수처럼 쓰는 값: 대문자/밑줄 (언어 차원의 상수 선언은 없다)
정수 최대_크기 = 10002. 코드 구조
# 1. 모듈 가져오기
가져오기 "stdlib/json"
# 2. 설정 값
정수 최대_재시도 = 3
# 3. 함수 정의
함수 초기화() {
출력("초기화")
}
# 4. 메인 로직
함수 메인() {
초기화()
}
# 5. 실행
메인()3. 에러 처리
# 실패할 수 있는 작업은 시도 블록으로 감싼다
함수 파일_처리(경로) {
시도 {
반환 파일_읽기(경로)
} 오류 (e) {
출력("파일 읽기 실패: " + e)
반환 없음
}
}
결과 = 파일_처리("없는_파일.txt")
# 파일 읽기 실패: RuntimeError: 파일을 열 수 없습니다: 없는_파일.txt
출력(결과) # 없음4. 문서화
# 함수 설명을 주석으로 작성
# 두 수의 합을 계산합니다
# 매개변수:
# - a: 첫 번째 정수
# - b: 두 번째 정수
# 반환: 두 수의 합
함수 더하기(a, b) {
반환 a + b
}FAQ
Q1: KingSejong은 어떤 프로젝트에 적합한가요?
A:
- 교육용 프로그래밍
- 한글 기반 스크립트
- 중소 규모 자동화 도구
- 데이터 처리 파이프라인
Q2: 성능은 어느 정도인가요?
A: 기본 실행기는 트리 순회 평가기다. --vm 은 바이트코드 VM 으로 같은 결과를 내며, 함수 호출이 많은 코드(피보나치 25)에서 평가기보다 약 20배 빠르다. 다른 언어와의 비교 수치는 저장소의 benchmarks/ 를 직접 돌려 확인한다.
Q3: 패키지 관리는 어떻게 하나요?
A: 아직 패키지 관리자가 없습니다. 모듈은 가져오기 로 파일 경로나 KINGSEJONG_PATH 에 둔 디렉토리에서 읽습니다. 예전의 ksjpm 은 저장소·다운로드 기능 없이 뼈대만 있어 제거했습니다.
Q4: 다른 언어와 연동할 수 있나요?
A: 현재는 독립 실행만 지원합니다. FFI (Foreign Function Interface)는 향후 계획에 있습니다.
Q5: 프로덕션에 사용할 수 있나요?
A: 1.0 이전 버전이다. 문법과 표준 라이브러리가 바뀔 수 있으므로 교육·실험·개인 도구에 맞다. 변경 사항은 CHANGELOG 에 적힌다.
Q6: 커뮤니티 지원은 어디서 받나요?
A:
- GitHub Issues: 버그 리포트 및 기능 요청
- GitHub Discussions: 질문 및 토론
- 문서: https://kingsejong-lang.github.io/kingsejong-lang/docs/
추가 리소스
- 튜토리얼: TUTORIAL.md - 단계별 학습
- 언어 레퍼런스: LANGUAGE_REFERENCE.md - 완전한 문법
- 표준 라이브러리: STDLIB_REFERENCE.md - stdlib 함수 목록
- 라이브러리 가이드: LIBRARY_GUIDE.md - 표준 라이브러리 확장
- 설치 가이드: INSTALL.md - 플랫폼별 설치
- 로드맵: ROADMAP.md - 개발 계획
라이선스: MIT