Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Han (한) Programming Language

Han is a statically-typed, compiled programming language where every keyword is written in Korean (Hangul). It compiles to native binaries through LLVM IR and includes a tree-walking interpreter for instant execution.

Quick Example

함수 인사(이름: 문자열) {
    출력("${이름}님 안녕하세요")
}

인사("세계")

Output: 세계님 안녕하세요

Key Features

  • Korean keywords함수, 만약, 이면, 반복, 변수
  • Korean word order만약 조건 이면 { }, 조건 동안 { } (SOV) and 동안 조건 { } (SVO)
  • String interpolation"${expr}" auto-desugars to 형식()
  • Korean logical operators그리고, 또는
  • Dual execution — interpreter (hgl interpret) and compiler (hgl build)
  • Toolinghgl check, hgl init, VS Code extension, and LSP support
  • Learning pathexamples/교육_*.hgl includes 10 SOV-first educational programs
  • Arrays, structs, enums, tuples, closures, pattern matching
  • Error handling시도 / 처리 with Elm-style source-context errors
  • File I/O, format strings, module imports

How It Works

Source (.hgl) → Lexer → Parser → AST → Interpreter (direct execution)
                                     → CodeGen → LLVM IR → clang → Binary

Installation

Prerequisites

  • Rust 1.70+
  • clang (for hgl build / hgl run) — optional for interpreter-only use

macOS

xcode-select --install

Linux

sudo apt install clang

Install Han

For most Rust users, install Han from crates.io:

cargo install han-lang

The crates.io package is named han-lang. The language name remains Han, and the installed command-line tool remains hgl.

The default crates.io install does not enable Python interop, so the CLI does not require a local Python dynamic library. Enable it explicitly with cargo install han-lang --features python if you need the 파이썬() / 파이썬_값() built-ins.

To install from a local checkout instead:

git clone https://github.com/xodn348/han.git
cd han
cargo install --path .

After either install path, hgl is available globally.

Verify Installation

hgl --help

Hello World

Create a file called hello.hgl:

출력("안녕하세요, 세계!")

Run it:

hgl interpret hello.hgl

Output:

안녕하세요, 세계!

With a Function

함수 main() {
    출력("Hello from Han!")
}

main()

Compile to Binary

hgl build hello.hgl    # creates ./hello binary
./hello                 # runs natively

REPL

Start the interactive REPL:

hgl repl
Han (한) REPL v0.2.1
종료: Ctrl+D 또는 '나가기' 입력

한> 변수 x = 42
한> 출력(x * 2)
84
한> 나가기

안녕히 가세요!

The REPL maintains state between lines — variables and functions persist across inputs.

Learn Korean Through Coding

Every keyword in Han is a real Korean word. If you're learning Korean, writing Han code is a way to practice reading Hangul in context.

Keyword Pronunciation Guide

CodePronunciationMeaningWhat it does
함수ham-sufunction (math term)defines a function
만약man-yakif/supposestarts a conditional
이면i-myeonthen/if-thenmarks the Korean-default conditional ending
반환ban-hwanreturn/give backreturns a value
변수byeon-suvariable (math term)declares a mutable variable
상수sang-suconstantdeclares an immutable constant
반복ban-bokrepetitionfor loop
동안dong-anduring/whilewhile loop
출력chul-ryeokoutputprints to console
입력ip-ryeokinputreads from console
chamtrue/truthboolean true
거짓geo-jitfalse/lieboolean false
없음eop-seumnothing/nonenull value
구조gu-jostructuredefines a struct
열거yeol-geoenumerationdefines an enum
아니면a-ni-myeonotherwiseelse branch
멈춰meom-chwostopbreak
계속gye-sokcontinuecontinue
시도si-doattempttry block
처리cheo-rihandling/processcatch block
맞춤mat-chwomatch/fitpattern matching
포함po-haminclude/containimport module
그리고geu-ri-goand (conjunction)logical AND
또는tto-neunor (alternative)logical OR
안에서an-e-seoinside/withinfor-in iteration

Method Names

Array and string methods are also real Korean verbs:

MethodPronunciationMeaning
추가chu-gaadd/append
삭제sak-jedelete/remove
포함po-hamcontain/include
정렬jeong-ryeolsort/arrange
역순yeok-sunreverse order
분리bun-riseparate/split
바꾸기ba-kku-gichange/replace
합치기hap-chi-gicombine/join
길이gi-rilength

Type Names

TypePronunciationMeaning
정수jeong-suinteger (whole number)
실수sil-sureal number (float)
문자열mun-ja-yeolcharacter string
bulboolean (fire/light)

Example: Reading Han Code as Korean

함수 인사(이름: 문자열) {
    출력("${이름}님 안녕하세요")
}

Reading this as Korean:

  • 함수 (function) 인사 (greeting) — "define a greeting function"
  • 이름 (name): 문자열 (string) — "parameter: name of type string"
  • 출력 (output) — "print"
  • ${이름} — insert the 이름 variable into the string
  • 안녕하세요 (annyeonghaseyo) — "hello" (formal)

Every line is readable Korean.

Language Guide

A tour of Han's syntax — variables, functions, conditionals, and loops. For deeper coverage of any single feature, see the dedicated pages under "Language Reference" in the sidebar.

Variables and Constants

변수 이름 = 42              // mutable variable
변수 메시지 = "안녕하세요"     // string variable
상수 파이 = 3.14            // immutable constant

With explicit type annotations:

변수 나이: 정수 = 25
변수 키: 실수 = 175.5
변수 이름: 문자열 = "홍길동"
변수 활성: 불 = 참

Functions

함수 더하기(가: 정수, 나: 정수) -> 정수 {
    반환 가 + 나
}

함수 인사(이름: 문자열) {
    출력("안녕하세요, " + 이름)
}

Conditionals

Han still supports the older minimal conditional form, but the Korean-default docs style uses 이면:

만약 점수 >= 90 이면 {
    출력("A")
} 아니면 점수 >= 80 이면 {
    출력("B")
} 아니면 {
    출력("C")
}

Loops

For loop (반복):

반복 변수 i = 0; i < 10; i += 1 {
    출력(i)
}

While loop (동안):

SOV:

변수 n = 0
n < 5 동안 {
    출력(n)
    n += 1
}

SVO alternative:

변수 n = 0
동안 n < 5 {
    출력(n)
    n += 1
}

Loop control멈춰 (break) and 계속 (continue):

반복 변수 i = 0; i < 100; i += 1 {
    만약 i == 50 이면 {
        멈춰
    }
    만약 i % 2 == 0 이면 {
        계속
    }
    출력(i)
}

Keyword Reference

KeywordMeaningEnglish Equivalent
함수function definitionfn / function
반환return valuereturn
변수mutable variablelet mut / var
상수immutable constantconst
만약conditionalif
이면conditional markerthen / if-then
아니면else branchelse
그리고and (logical)&&
또는or (logical)`
반복for loopfor
동안while loopwhile
멈춰break loopbreak
계속continue loopcontinue
boolean truetrue
거짓boolean falsefalse
출력print to consoleprint
입력read from consoleinput

Type System & Operators

TypeDescriptionLLVM TypeExamples
정수64-bit integeri6442, -10
실수64-bit floatf643.14, -0.5
문자열UTF-8 stringi8*"안녕하세요"
booleani1, 거짓
없음void / no valuevoid(function return type)
OperatorDescription
+, -, *, /, %Arithmetic
==, !=Equality
<, >, <=, >=Comparison
&&, ||, !, 그리고, 또는Logical
=, +=, -=, *=, /=Assignment

Variables & Constants

Mutable Variables

변수 이름 = 42
변수 메시지 = "안녕하세요"
이름 = 100    // reassignment allowed

Constants

상수 파이 = 3.14
// 파이 = 3.0  → runtime error: cannot reassign constant

Type Annotations

변수 나이: 정수 = 25
변수 키: 실수 = 175.5
변수 이름: 문자열 = "홍길동"
변수 활성: 불 = 참

Null Values

변수 값 = 없음
출력(값)    // 없음

Data Types

Primitive Types

TypeHanDescriptionExamples
Integer정수64-bit signed integer42, -10, 0
Float실수64-bit floating point3.14, -0.5
String문자열UTF-8 string"안녕하세요"
Booleantrue/false, 거짓
Void없음null/void없음

Type Coercion

Int and Float mix automatically:

출력(1 + 1.5)     // 2.5 (Float)
출력(3 * 2.0)     // 6.0 (Float)
출력(10 - 0.5)    // 9.5 (Float)

Compound Types

  • Arrays: [1, 2, 3] — type [정수]
  • Tuples: (1, "hello", 참) — type (정수, 문자열, 불)
  • Structs: 구조 사람 { 이름: 문자열 }
  • Enums: 열거 방향 { 위, 아래 }

Functions

Declaration

함수 더하기(가: 정수, 나: 정수) -> 정수 {
    반환 가 + 나
}

Calling

변수 결과 = 더하기(3, 4)
출력(결과)    // 7

No Return Type (void)

함수 인사(이름: 문자열) {
    출력(형식("안녕, {0}!", 이름))
}

Recursion

함수 피보나치(n: 정수) -> 정수 {
    만약 n <= 1 이면 {
        반환 n
    }
    반환 피보나치(n - 1) + 피보나치(n - 2)
}

Generics (syntax only)

함수 첫번째<T>(arr: [T]) -> T {
    반환 arr[0]
}

Type parameters are parsed but erased at runtime.

Function Type Parameter

함수 적용(f: 함수, x: 정수) -> 정수 {
    반환 f(x)
}

Control Flow

If / Else-If / Else

The Korean-default conditional form uses 이면. The older minimal form is still supported, but the docs use the 이면 style:

만약 점수 >= 90 이면 {
    출력("A")
} 아니면 점수 >= 80 이면 {
    출력("B")
} 아니면 {
    출력("C")
}

Logical Operators

만약 로그인됨 그리고 관리자 이면 {
    출력("관리자 메뉴")
}

만약 오프라인 또는 점검중 이면 {
    출력("잠시 후 다시 시도하세요")
}

For Loop

반복 변수 i = 0; i < 10; i += 1 {
    출력(i)
}

For-In Loop

Iterate over arrays:

반복 과일 안에서 ["사과", "배", "포도"] {
    출력(과일)
}

Iterate over strings:

반복 글자 안에서 "한글" {
    출력(글자)    // 한, 글
}

Iterate over ranges:

반복 i 안에서 0..5 {
    출력(i)    // 0, 1, 2, 3, 4
}

While Loop

SOV:

변수 n = 0
n < 5 동안 {
    출력(n)
    n += 1
}

SVO (traditional alternative):

변수 n = 0
동안 n < 5 {
    출력(n)
    n += 1
}

Break and Continue

반복 i 안에서 0..100 {
    만약 i == 50 이면 { 멈춰 }
    만약 i % 2 == 0 이면 { 계속 }
    출력(i)
}

Range Operator

변수 범위 = 0..10     // creates [0, 1, 2, ..., 9]
변수 길이 = 범위.길이()  // 10

Arrays

Creating Arrays

변수 숫자 = [1, 2, 3, 4, 5]
변수 빈배열 = []

Indexing

출력(숫자[0])     // 1
출력(숫자[-1])    // 5 (negative indexing)
숫자[0] = 99      // mutation

Methods

MethodDescriptionExample
.추가(값)Append elementarr.추가(6)
.삭제(인덱스)Remove at indexarr.삭제(0)
.길이()Lengtharr.길이()5
.포함(값)Containsarr.포함(3)
.역순()Reverse (new array)arr.역순()
.정렬()Sort (new array)arr.정렬()
.합치기(구분자)Join to stringarr.합치기(", ")

Iteration

반복 항목 안에서 [1, 2, 3] {
    출력(항목)
}

Structs

Definition

구조 사람 {
    이름: 문자열,
    나이: 정수
}

Instantiation

변수 홍길동 = 사람 { 이름: "홍길동", 나이: 30 }

Field Access

출력(홍길동.이름)    // 홍길동
출력(홍길동.나이)    // 30

Field Mutation

홍길동.나이 = 31

Nested Structs

구조 주소 { 도시: 문자열 }
구조 직원 { 이름: 문자열, 주소: 주소 }

변수 p = 직원 { 이름: "김철수", 주소: 주소 { 도시: "서울" } }
출력(p.주소.도시)        // 서울
p.주소.도시 = "부산"     // nested mutation

Impl Blocks (Methods)

구현 사람 {
    함수 소개(자신: 사람) {
        출력(형식("{0}, {1}세", 자신.이름, 자신.나이))
    }
}

홍길동.소개()    // 홍길동, 30세

자신 is the self parameter — refers to the struct instance.

Enums

Definition

열거 방향 {
    위,
    아래,
    왼쪽,
    오른쪽
}

Access

Variants are accessed with :::

출력(방향::위)       // 0
출력(방향::아래)     // 1
출력(방향::오른쪽)   // 3

Variants are integer values starting from 0.

Pattern Matching with Enums

맞춤 방향::아래 {
    0 => 출력("위")
    1 => 출력("아래")
    _ => 출력("기타")
}

Tuples

Creating Tuples

변수 좌표 = (10, 20)
변수 사람 = ("홍길동", 30, 참)

Access by Index

출력(좌표.0)    // 10
출력(좌표.1)    // 20
출력(사람.0)    // 홍길동

As Return Type

함수 최소최대(arr: [정수]) -> (정수, 정수) {
    변수 최소 = arr[0]
    변수 최대 = arr[0]
    반복 v 안에서 arr {
        만약 v < 최소 이면 { 최소 = v }
        만약 v > 최대 이면 { 최대 = v }
    }
    반환 (최소, 최대)
}

변수 결과 = 최소최대([5, 1, 9, 3, 7])
출력(형식("최소: {0}, 최대: {1}", 결과.0, 결과.1))

Closures

Anonymous Functions

변수 두배 = 함수(x: 정수) { 반환 x * 2 }
출력(두배(5))    // 10

Environment Capture

Closures capture variables from their enclosing scope:

변수 배수 = 3
변수 곱하기 = 함수(x: 정수) { 반환 x * 배수 }
출력(곱하기(5))    // 15

Passing as Arguments

함수 적용(f: 함수, x: 정수) -> 정수 {
    반환 f(x)
}

변수 제곱 = 함수(x: 정수) { 반환 x * x }
출력(적용(제곱, 4))    // 16

Pattern Matching

Basic Match

맞춤 값 {
    1 => 출력("하나")
    2 => 출력("둘")
    _ => 출력("기타")
}

With Blocks

맞춤 상태 {
    "활성" => {
        출력("활성 상태")
        처리하기()
    }
    "비활성" => 출력("비활성")
    _ => 출력("알 수 없음")
}

Pattern Types

PatternExampleDescription
Integer42Matches exact integer
String"hello"Matches exact string
Boolean, 거짓Matches boolean
Wildcard_Matches anything
BindingxMatches anything, binds to variable x
Array[1, 2, 3]Matches array structure

Variable Binding

맞춤 값 {
    0 => 출력("영")
    n => 출력(형식("값: {0}", n))
}

Error Handling

Try / Catch

시도 {
    변수 내용 = 파일읽기("없는파일.txt")
    출력(내용)
} 처리(오류) {
    출력(형식("에러: {0}", 오류))
}

The error variable (오류) contains the error message as a string. V2 errors use Elm-style messaging with source context, so the printed text points back to the original code location.

What Gets Caught

  • Division by zero
  • File not found
  • Index out of bounds
  • Undefined variable access
  • Type mismatches at runtime

Example: Safe Division

함수 안전나누기(a: 정수, b: 정수) -> 정수 {
    시도 {
        반환 a / b
    } 처리(오류) {
        출력(형식("나누기 실패: {0}", 오류))
        반환 0
    }
}

Example error shape:

타입 오류: 정수를 기대했지만 문자열을 받았습니다
 --> main.hgl:3:10
  |
3 | 변수 x: 정수 = "hello"
  |          ^^^^^^^^^^^^^ 여기서 타입이 맞지 않습니다

Modules

Importing Files

포함 "수학도구.hgl"

This executes the file and imports all its definitions (functions, variables, structs) into the current scope.

Duplicate Includes

Han tracks imported files by canonical path and skips duplicate includes.

포함 "utils.hgl"
포함 "./utils.hgl"   // same file -> skipped

This keeps include behavior idempotent for repeated module wiring.

Example

수학도구.hgl:

함수 최대값(a: 정수, b: 정수) -> 정수 {
    만약 a > b 이면 { 반환 a }
    반환 b
}

main.hgl:

포함 "수학도구.hgl"
출력(최대값(10, 20))    // 20

String Methods

MethodDescriptionExampleResult
.길이()Character count"한글".길이()2
.분리(sep)Split by separator"a,b,c".분리(",")["a", "b", "c"]
.포함(s)Contains substring"hello".포함("ell")
.바꾸기(from, to)Replace"hello".바꾸기("l", "r")"herro"
.앞뒤공백제거()Trim whitespace" hi ".앞뒤공백제거()"hi"
.대문자()Uppercase"hello".대문자()"HELLO"
.소문자()Lowercase"HELLO".소문자()"hello"
.시작(s)Starts with"hello".시작("he")
.끝(s)Ends with"hello".끝("lo")

String Indexing

변수 s = "한글"
출력(s[0])    // 한
출력(s[1])    // 글

String Iteration

반복 글자 안에서 "한글" {
    출력(글자)
}

Concatenation

변수 full = "안녕" + "하세요"
출력(full)    // 안녕하세요

Array Methods

MethodDescriptionExampleResult
.추가(값)Appendarr.추가(6)mutates in place
.삭제(인덱스)Remove at indexarr.삭제(0)returns removed value
.길이()Lengtharr.길이()5
.포함(값)Containsarr.포함(3)
.역순()Reversearr.역순()new reversed array
.정렬()Sortarr.정렬()new sorted array
.합치기(구분자)Join to stringarr.합치기(", ")"1, 2, 3"

HashMap / Dictionary

Creating a Map

변수 점수 = 사전("수학", 95, "영어", 88, "과학", 92)
변수 빈맵 = 사전()

Arguments are key-value pairs: 사전(key1, val1, key2, val2, ...).

Access and Mutation

출력(점수["수학"])       // 95
점수["국어"] = 100       // add new key
점수["수학"] = 99        // update existing

Methods

MethodDescriptionExample
.키목록()All keys as array점수.키목록()["수학", "영어", "과학"]
.값목록()All values as array점수.값목록()[95, 88, 92]
.길이()Number of entries점수.길이()3
.포함(키)Key exists점수.포함("수학")
.삭제(키)Remove key점수.삭제("영어")

Iteration

변수 키들 = 점수.키목록()
반복 키 안에서 키들 {
    출력(형식("{0}: {1}", 키, 점수[키]))
}

I/O

Output

출력("안녕하세요")        // print to stdout
출력(42)                 // prints any value
출력("이름:", 이름)       // multiple args, space-separated
출력오류("에러 메시지")    // print to stderr

Input

변수 이름 = 입력()
출력(형식("안녕, {0}!", 이름))

입력() reads one line from stdin and returns it as a string.

Math Functions

FunctionDescriptionExampleResult
제곱근(x)Square root제곱근(16.0)4.0
절댓값(x)Absolute value절댓값(-5)5
거듭제곱(밑, 지수)Power거듭제곱(2, 10)1024.0
사인(x)Sine사인(파이() / 2.0)1.0
코사인(x)Cosine코사인(0.0)1.0
탄젠트(x)Tangent
로그(x)Natural log (ln)로그(자연상수())1.0
로그10(x)Log base 10
지수(x)e^x지수(1.0)2.718...
올림(x)Ceiling올림(2.3)3.0
내림(x)Floor내림(2.9)2.0
반올림(x)Round반올림(2.5)3.0
최대(a, b)Maximum최대(3, 7)7.0
최소(a, b)Minimum
난수()Random 0~1
난수(a, b)Random int a~b난수(1, 10)
파이()Pi constant3.14159...
자연상수()Euler's number2.71828...
행렬곱(A, B)Matrix multiply행렬곱(A, B)[[실수]]
전치(A)Matrix transpose전치(A)[[실수]]
스칼라곱(A, s)Scalar multiply스칼라곱(A, 2.0)[[실수]]
행렬합(A, B)Matrix addition행렬합(A, B)[[실수]]
행렬차(A, B)Matrix subtraction행렬차(A, B)[[실수]]
내적(a, b)Dot product내적([1,2], [3,4])11.0
외적(a, b)Cross product (3D)외적([1,0,0], [0,1,0])[0,0,1]
단위행렬(n)Identity matrix단위행렬(3)[[1,0,0],...]
텐서곱(A, B)Tensor/Kronecker product텐서곱(A, B)[[실수]]

All math functions accept both 정수 and 실수 inputs.

Matrix Operations

행렬곱 and 전치 work with 2D arrays (array of arrays):

변수 A = [[1.0, 2.0], [3.0, 4.0]]
변수 B = [[5.0, 6.0], [7.0, 8.0]]

변수 결과 = 행렬곱(A, B)
// [[19.0, 22.0], [43.0, 50.0]]

변수 T = 전치(A)
// [[1.0, 3.0], [2.0, 4.0]]

These can be used to implement algorithms like self-attention (Attention(Q,K,V) = softmax(QK^T / √d_k) × V). See examples/어텐션.hgl for a full implementation.

Type Conversion

FunctionDescriptionExampleResult
정수변환(x)Convert to integer정수변환("42")42
실수변환(x)Convert to float실수변환(42)42.0
길이(s)String length길이("한글")2

Conversion Rules

정수변환(3.14)      // 3 (truncates)
정수변환("42")      // 42 (parse string)
정수변환(참)        // 1
정수변환(거짓)      // 0

실수변환(42)        // 42.0
실수변환("3.14")    // 3.14

Format Strings

Positional Arguments

형식("이름: {0}, 나이: {1}", "홍길동", 30)
// → "이름: 홍길동, 나이: 30"

Named Arguments (from scope)

변수 이름 = "홍길동"
변수 나이 = 30
형식("이름: {이름}, 나이: {나이}")
// → "이름: 홍길동, 나이: 30"

String Interpolation

변수 이름 = "홍길동"
출력("${이름}님 안녕하세요")
// desugars to: 출력(형식("{0}님 안녕하세요", 이름))

Named mode substitutes {변수명} with the variable's value from the current scope. Interpolated strings are automatically desugared to 형식().

출력("합: ${1 + 2}")
// desugars to: 출력(형식("합: {0}", 1 + 2))

Use interpolation for simple expressions. 형식() remains the most explicit option for complex templates.

File I/O

FunctionDescriptionExample
파일읽기(경로)Read file to string파일읽기("data.txt")
파일쓰기(경로, 내용)Write string to file파일쓰기("out.txt", "hello")
파일추가(경로, 내용)Append to file파일추가("log.txt", "line\n")
파일존재(경로)Check if file exists파일존재("data.txt")/거짓

Example: Read and Process

시도 {
    변수 내용 = 파일읽기("data.txt")
    변수 줄들 = 내용.분리("\n")
    반복 줄 안에서 줄들 {
        출력(줄)
    }
} 처리(오류) {
    출력(형식("파일 오류: {0}", 오류))
}

JSON

Powered by Rust's serde_json crate.

Parse JSON

변수 텍스트 = "{\"이름\": \"홍길동\", \"나이\": 30}"
변수 데이터 = 제이슨_파싱(텍스트)
출력(데이터["이름"])    // 홍길동
출력(데이터["나이"])    // 30

JSON objects become 사전, arrays become 배열.

Generate JSON

변수 사용자 = 사전("이름", "홍길동", "나이", 30)
변수 json = 제이슨_생성(사용자)
출력(json)    // {"나이":30,"이름":"홍길동"}

Pretty Print

변수 예쁜 = 제이슨_예쁘게(사용자)
출력(예쁜)

Functions

FunctionDescription
제이슨_파싱(문자열)Parse JSON string → Han value
제이슨_생성(값)Han value → JSON string
제이슨_예쁘게(값)Han value → pretty-printed JSON

HTTP

Powered by Rust's reqwest crate (blocking mode).

GET Request

변수 응답 = HTTP_포함("https://httpbin.org/get")
출력(응답)

POST Request

변수 본문 = 제이슨_생성(사전("이름", "홍길동"))
변수 응답 = HTTP_보내기("https://httpbin.org/post", 본문)
출력(응답)

POST sends with Content-Type: application/json. If the body is not a string, it's auto-converted to JSON.

Error Handling

시도 {
    변수 응답 = HTTP_포함("https://invalid-url.example")
} 처리(오류) {
    출력(형식("HTTP 오류: {0}", 오류))
}

Functions

FunctionDescription
HTTP_포함(url)GET request → response body as string
HTTP_보내기(url, body)POST request with JSON body → response as string

Regex

Powered by Rust's regex crate.

Find All Matches

변수 결과 = 정규식_찾기("[0-9]+", "abc 123 def 456")
출력(결과)    // [123, 456]

Test Match

출력(정규식_일치("^[0-9]+$", "12345"))    // 참
출력(정규식_일치("^[0-9]+$", "abc"))      // 거짓

Replace

변수 결과 = 정규식_바꾸기("[0-9]+", "전화: 010-1234-5678", "***")
출력(결과)    // 전화: ***-***-***

Functions

FunctionDescription
정규식_찾기(패턴, 텍스트)Find all matches → array of strings
정규식_일치(패턴, 텍스트)Test if pattern matches → bool
정규식_바꾸기(패턴, 텍스트, 대체)Replace all matches → string

Date & Time

Powered by Rust's chrono crate.

Current Time

출력(현재시간())    // 2025-03-15 12:30:45
출력(현재날짜())    // 2025-03-15
출력(타임스탬프())  // 1710500000 (Unix timestamp)

Functions

FunctionReturnExample
현재시간()문자열"2025-03-15 12:30:45"
현재날짜()문자열"2025-03-15"
타임스탬프()정수1710500000

현재시간() and 현재날짜() use local time. 타임스탬프() returns UTC Unix timestamp.

System & Process

Shell Command

변수 결과 = 실행("ls -la")
출력(결과)

Runs the command via sh -c and returns stdout as a string.

Environment Variables

변수 홈 = 환경변수("HOME")
출력(홈)    // /Users/username

변수 없는변수 = 환경변수("NONEXISTENT")
출력(없는변수)    // 없음

Returns 없음 if the variable doesn't exist.

CLI Arguments

변수 인자들 = 명령인자()
반복 인자 안에서 인자들 {
    출력(인자)
}

Returns arguments passed after the filename: hgl interpret file.hgl arg1 arg2

Sleep

잠자기(1000)    // sleep 1 second (1000 milliseconds)

Type Introspection

출력(타입(42))          // 정수
출력(타입("hello"))     // 문자열
출력(타입([1,2,3]))     // 배열
출력(타입(사전()))      // 사전
출력(타입(참))          // 불

Functions

FunctionDescription
실행(명령어)Run shell command → stdout string
환경변수(이름)Get env var → string or 없음
명령인자()CLI args → array of strings
잠자기(밀리초)Sleep for N milliseconds
타입(값)Type name → string
출력오류(값)Print to stderr

Examples Index

Han ships with a growing set of example programs in the examples/ directory of the repository. Each file is a self-contained .hgl program you can run with:

hgl interpret examples/<name>.hgl

Tutorial Series (교육)

A 10-step progressive tutorial covering the language from basics to integration:

Classic Algorithms

FileTopic
피보나치.hglFibonacci (recursive)
피보나치_SOV.hglFibonacci with SOV 동안 form
팩토리얼.hglFactorial
소수판별.hglPrime number check
정렬알고리즘.hglSorting algorithms
합계.hglSum 1..n
구구단.hglMultiplication table
별찍기.hglStar pattern printing
짝홀.hglEven/odd checker

Strings, Arrays, Structures

FileTopic
문자열보간.hglString interpolation
단어세기.hglWord counter
배열연산.hglArray operations
구조체메서드.hglStruct methods
패턴매칭.hglPattern matching
범위반복.hglRange iteration
클로저고차.hglHigher-order closures
할일목록.hglTodo list with structs
한글연산자.hglKorean logical operators

I/O and Systems

FileTopic
파일처리.hglFile read/write
에러처리.hgl시도/처리 error handling
정규식.hglRegex
JSON처리.hglJSON parsing and generation
HTTP_API.hglHTTP GET/POST
시스템정보.hglSystem / environment info
온도변환.hglTemperature conversion

Mini Apps

FileTopic
계산기.hglString calculator
가위바위보.hglRock-paper-scissors
어텐션.hglAttention mechanism demo
안녕.hglHello world

Sample: Factorial

함수 팩토리얼(n: 정수) -> 정수 {
    만약 n <= 1 이면 {
        반환 1
    }
    반환 n * 팩토리얼(n - 1)
}

함수 main() {
    출력(팩토리얼(10))
}

main()

Output: 3628800

Sample: Sum 1 to 100

함수 합계(n: 정수) -> 정수 {
    변수 합 = 0
    반복 변수 i = 1; i <= n; i += 1 {
        합 += i
    }
    반환 합
}

함수 main() {
    출력(합계(100))
}

main()

Output: 5050

CLI Usage

hgl interpret <file.hgl>    Run with interpreter
hgl build <file.hgl>        Compile to native binary
hgl run <file.hgl>          Compile and run immediately
hgl check <file.hgl>        Type-check only (no execution)
hgl init [name]             Create new Han project
hgl repl                    Interactive REPL
hgl lsp                     Start LSP server

Examples

hgl interpret examples/피보나치.hgl
hgl check examples/합계.hgl
hgl build examples/합계.hgl && ./합계
hgl init hello-han
hgl repl

hgl check (Type Check Only)

hgl check parses and type-checks a file without running interpreter/codegen.

hgl check examples/합계.hgl
  • Success: prints ✓ 타입 검사 통과
  • Failure: prints parser/type diagnostics and exits with non-zero status

hgl init (Project Scaffold)

hgl init hello-han

Creates:

  • hello-han/main.hgl
  • hello-han/.gitignore

Default main.hgl prints 안녕하세요!.

VS Code Extension

Install from Source

cd editors/vscode
npm install
npm run compile

Press F5 in VS Code to launch with the extension loaded.

Features

  • Syntax highlighting for .hgl files
  • Keyword, type, builtin, string, number, comment coloring
  • Auto-closing brackets and quotes
  • LSP integration (hover docs + completion)

LSP Setup

Make sure hgl is in your PATH:

cargo install --path .

The extension automatically starts hgl lsp when you open a .hgl file.

Compiler Architecture

How the Han toolchain is organized — from .hgl source text to either a tree-walked result or a native binary.

How Han Works

Han follows the classical compiler pipeline, implemented entirely in Rust with zero external compiler dependencies (LLVM IR is generated as plain text):

Source (.hgl)
    │
    ▼
┌─────────┐     ┌─────────┐     ┌─────────┐
│  Lexer  │ ──▶ │ Parser  │ ──▶ │   AST   │
│(lexer.rs)│    │(parser.rs)│   │ (ast.rs) │
└─────────┘     └─────────┘     └────┬────┘
                                     │
                        ┌────────────┼────────────┐
                        ▼                         ▼
                ┌──────────────┐         ┌──────────────┐
                │ Interpreter  │         │   CodeGen    │
                │(interpreter.rs)│       │ (codegen.rs) │
                └──────┬───────┘         └──────┬───────┘
                       │                        │
                       ▼                        ▼
                  Direct Output           LLVM IR (.ll)
                                               │
                                               ▼
                                         clang → Binary

Project Structure

han/
├── src/
│   ├── main.rs          CLI entry point (hgl command)
│   ├── lexer.rs         Lexer: Korean source → token stream
│   ├── parser.rs        Parser: tokens → AST (recursive descent)
│   ├── ast.rs           AST node type definitions
│   ├── interpreter.rs   Tree-walking interpreter
│   ├── codegen.rs       LLVM IR text code generator
│   └── lsp.rs           LSP server (hover + completion)
├── editors/
│   └── vscode/          VS Code extension (syntax highlighting + LSP)
├── examples/            Example .hgl programs
├── spec/
│   └── SPEC.md          Formal language specification (EBNF)
└── tests/               Integration tests

Design Decisions

Why text-based LLVM IR instead of the LLVM C API? Han generates LLVM IR as plain text strings, avoiding the complexity of linking against LLVM libraries. This keeps the build simple (cargo build — no LLVM installation required) while still producing optimized native binaries through clang.

Why both interpreter and compiler? The interpreter enables instant execution without any toolchain dependencies beyond Rust. The compiler path exists for production use where performance matters. Same parser, same AST, two backends.

Why Rust? Rust's enum types map naturally to AST nodes and token variants. Pattern matching makes parser and interpreter logic clear and exhaustive. Memory safety without garbage collection suits a language toolchain.

Lexer & Token Analysis

This page covers Han's lexer (the lexer.rs stage that turns Korean source text into a token stream) and how Korean source code interacts with modern AI/LLM tokenizers.

Token Analysis (AI/LLM)

We tested Han code against Python and JavaScript using GPT-4o's tokenizer (tiktoken):

ProgramHanPythonJavaScript
Fibonacci88 tokens54 tokens69 tokens

Han uses more tokens, not fewer. Korean keywords average 2-3 tokens each vs 1 for English. This is because BPE (Byte Pair Encoding) tokenizers are trained on English-dominant data — function appears billions of times and merges into a single token, while 함수 is rare and gets split into byte-level pieces.

This is a tokenizer training bias, not a property of Korean. If BPE were trained on Korean-heavy data, 함수 could easily be a single token.

Relevant discussion: Ukrainian LLM Lapa replaced 80K tokens and achieved 1.5x efficiency

Why this matters for Han

This finding is part of Han's mission. From the project README:

LLMs are trained on English-dominant data. BPE tokenizers treat Korean characters as rare, splitting 함수 into multiple byte-level tokens while function becomes one. The more Korean code exists on the internet — in repos, in documentation, in examples — the better future tokenizers will represent the Korean language. Han is a small contribution to that corpus.

The current cost is real (more tokens per request when an LLM reads Han), but the long-term benefit accrues to every Korean-language application — not just programming languages.

Keyword Reference

Control Keywords

KeywordEnglishSyntax
함수function함수 이름(매개변수: 타입) -> 반환타입 { }
반환return반환 값
변수let (mutable)변수 이름 = 값
상수const상수 이름 = 값
만약if만약 조건 이면 { }
이면then/if-then만약 조건 이면 { }
아니면else아니면 { } or 아니면 조건 이면 { }
그리고and (logical)a 그리고 b
또는or (logical)a 또는 b
반복for반복 변수 i = 0; i < n; i += 1 { }
동안while조건 동안 { } or 동안 조건 { }
멈춰break멈춰
계속continue계속
안에서in (for-in)반복 x 안에서 배열 { }

Type Keywords

KeywordEnglishLLVM
정수inti64
실수floatf64/double
문자열stringi8*
booli1
없음void/nullvoid

Structure Keywords

KeywordEnglishSyntax
구조struct구조 이름 { 필드: 타입 }
구현impl구현 구조체 { 함수 메서드(자신: T) { } }
열거enum열거 이름 { 변형1, 변형2 }
시도try시도 { } 처리(오류) { }
처리catch처리(오류) { }
맞춤match맞춤 값 { 패턴 => 결과 }
포함import포함 "파일.hgl"

Literal Keywords

KeywordEnglish
true
거짓false
없음null/void

Built-in Functions

FunctionSignatureDescription
출력(값)(any...) -> 없음Print to stdout
입력()() -> 문자열Read line from stdin
제곱근(x)(숫자) -> 실수Square root
절댓값(x)(숫자) -> 숫자Absolute value
거듭제곱(밑, 지수)(숫자, 숫자) -> 실수Power
정수변환(x)(any) -> 정수Convert to integer
실수변환(x)(any) -> 실수Convert to float
길이(s)(문자열) -> 정수String length
형식(template, ...)(문자열, any...) -> 문자열Format string
파일읽기(경로)(문자열) -> 문자열Read file
파일쓰기(경로, 내용)(문자열, 문자열) -> 없음Write file
파일추가(경로, 내용)(문자열, 문자열) -> 없음Append to file
파일존재(경로)(문자열) -> 불File exists
출력오류(값)(any...) -> 없음Print to stderr

Complete API Reference

This page is optimized for LLM consumption. It contains every keyword, type, builtin, method, and operator in Han in a structured, machine-readable format.

Language: Han (한)

File Extension: .hgl

Execution: hgl interpret <file>, hgl build <file>, hgl check <file>, or hgl init [name]


KEYWORDS

함수    → function definition
반환    → return
변수    → mutable variable (let)
상수    → immutable constant (const)
만약    → if
이면    → then (conditional marker)
아니면  → else
그리고  → logical and
또는    → logical or
반복    → for loop
동안    → while loop
멈춰    → break
계속    → continue
안에서  → in (for-in iteration)
구조    → struct definition
구현    → impl block
열거    → enum definition
시도    → try
처리    → catch
맞춤    → match (pattern matching)
포함    → import
참      → true
거짓    → false
없음    → null/void

TYPES

정수    → i64 (64-bit integer)
실수    → f64 (64-bit float)
문자열  → String (UTF-8)
불      → bool
없음    → void
[정수]  → Array of integers
(정수, 문자열) → Tuple

OPERATORS

+  -  *  /  %           → arithmetic
== !=  <  >  <=  >=     → comparison
&& || !                 → logical
그리고 또는              → Korean logical aliases
|>                      → pipe operator
=  +=  -=  *=  /=       → assignment
->                      → return type arrow
=>                      → match arm arrow
..                      → range (0..10)
::                      → enum access (방향::위)
.                       → field/method access

BUILTIN FUNCTIONS

출력(값...)              → print to stdout
입력()                   → read line from stdin → 문자열
출력오류(값...)           → print to stderr
제곱근(x)                → sqrt(x) → 실수
절댓값(x)                → abs(x) → 숫자
거듭제곱(밑, 지수)        → pow(base, exp) → 실수
사인(x)                  → sin(x) → 실수
코사인(x)                → cos(x) → 실수
탄젠트(x)                → tan(x) → 실수
로그(x)                  → ln(x) → 실수
로그10(x)                → log10(x) → 실수
지수(x)                  → e^x → 실수
올림(x)                  → ceil(x) → 실수
내림(x)                  → floor(x) → 실수
반올림(x)                → round(x) → 실수
최대(a, b)               → max(a, b) → 실수
최소(a, b)               → min(a, b) → 실수
난수()                   → random float 0..1 → 실수
난수(a, b)               → random int a..b → 정수
파이()                   → pi constant → 실수
자연상수()               → Euler's number → 실수
정수변환(x)              → int(x) → 정수
실수변환(x)              → float(x) → 실수
길이(s)                  → len(s) → 정수
행렬곱(A, B)             → matrix multiply → [[실수]]
전치(A)                  → matrix transpose → [[실수]]
스칼라곱(A, s)           → scalar multiply → [[실수]]
행렬합(A, B)             → matrix addition → [[실수]]
행렬차(A, B)             → matrix subtraction → [[실수]]
내적(a, b)               → dot product → 실수
외적(a, b)               → cross product (3D) → [실수]
단위행렬(n)              → identity matrix → [[실수]]
텐서곱(A, B)             → tensor/Kronecker product → [[실수]]
형식(template, args...)  → format string / interpolation target → 문자열
파일읽기(경로)            → read file → 문자열
파일쓰기(경로, 내용)      → write file
파일추가(경로, 내용)      → append to file
파일존재(경로)            → file exists → 불
사전(키, 값, ...)        → create HashMap → 사전
제이슨_파싱(문자열)       → parse JSON → value
제이슨_생성(값)           → value → JSON string
제이슨_예쁘게(값)         → value → pretty JSON string
HTTP_포함(url)        → GET request → 문자열
HTTP_보내기(url, body)    → POST request → 문자열
정규식_찾기(패턴, 텍스트)  → find matches → [문자열]
정규식_일치(패턴, 텍스트)  → test match → 불
정규식_바꾸기(패턴, 텍스트, 대체) → replace → 문자열
현재시간()               → current datetime → 문자열
현재날짜()               → current date → 문자열
타임스탬프()             → unix timestamp → 정수
실행(명령어)             → shell command → 문자열
환경변수(이름)           → env var → 문자열 or 없음
명령인자()               → CLI args → [문자열]
잠자기(밀리초)           → sleep
타입(값)                 → type name → 문자열
파이썬(코드)             → execute Python, return stdout → 문자열
파이썬_값(표현식)        → evaluate Python expression → 값

MAP METHODS

.키목록()        → all keys → [T]
.값목록()        → all values → [T]
.길이()          → entry count → 정수
.포함(키)        → key exists → 불
.삭제(키)        → remove entry → removed value

ARRAY METHODS

.추가(값)        → push element
.삭제(인덱스)    → remove at index → removed value
.길이()          → length → 정수
.포함(값)        → contains → 불
.역순()          → reversed copy → [T]
.정렬()          → sorted copy → [T]
.합치기(구분자)  → join to string → 문자열

STRING METHODS

.길이()          → character count → 정수
.분리(구분자)    → split → [문자열]
.포함(부분)      → contains → 불
.바꾸기(전, 후)  → replace → 문자열
.앞뒤공백제거()  → trim → 문자열
.대문자()        → uppercase → 문자열
.소문자()        → lowercase → 문자열
.시작(접두사)    → starts with → 불
.끝(접미사)      → ends with → 불

SYNTAX PATTERNS

// Variable declaration
변수 이름 = 값
변수 이름: 타입 = 값
상수 이름 = 값

// Function
함수 이름(매개변수: 타입) -> 반환타입 {
    반환 값
}

// If/else (Korean-default)
만약 조건 이면 {
    ...
} 아니면 조건2 이면 {
    ...
} 아니면 {
    ...
}

// Older minimal form is still supported, but docs prefer the `이면` pattern.

// For loop
반복 변수 i = 0; i < n; i += 1 {
    ...
}

// For-in
반복 항목 안에서 배열 {
    ...
}

// While (SOV default)
조건 동안 {
    ...
}

// While (SVO alternative)
동안 조건 {
    ...
}

// Struct
구조 이름 {
    필드: 타입,
    필드2: 타입
}

// Impl
구현 구조체이름 {
    함수 메서드(자신: 구조체이름) {
        ...
    }
}

// Enum
열거 이름 {
    변형1,
    변형2
}

// Match
맞춤 값 {
    패턴1 => 결과1
    패턴2 => { ... }
    _ => 기본값
}

// Try/catch
시도 {
    ...
} 처리(오류변수) {
    ...
}

// Import
포함 "파일.hgl"

// Closure
변수 f = 함수(x: 정수) { 반환 x * 2 }

// Tuple
변수 t = (1, "hello", 참)
t.0  // 1

// Range
0..10  // [0, 1, 2, ..., 9]

// Array
변수 arr = [1, 2, 3]
arr[0]      // indexing
arr[-1]     // negative indexing
arr[0] = 99 // mutation