@uiwwsw/hangulscript 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/LANGUAGE.md +148 -83
- package/README.md +51 -50
- package/dist/checker.js +80 -0
- package/dist/cli.js +7 -11
- package/dist/diagnostics.js +61 -0
- package/dist/editor.d.ts +5 -0
- package/dist/editor.js +50 -0
- package/dist/emitter.js +39 -0
- package/dist/expressions.js +59 -0
- package/dist/formatter.d.ts +2 -0
- package/dist/formatter.js +29 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +33 -139
- package/dist/loader.js +16 -0
- package/dist/register.js +2 -0
- package/dist/runtime.js +44 -0
- package/dist/sentences.js +133 -92
- package/dist/transformer.d.ts +3 -0
- package/dist/transformer.js +9 -334
- package/dist/vite.js +18 -11
- package/docs/frameworks.md +152 -0
- package/docs/support.md +42 -0
- package/examples/calculator-ui.hgs +0 -1
- package/examples/calculator.hgs +0 -1
- package/examples/discount-ui.hgs +0 -1
- package/examples/discount.hgs +0 -1
- package/examples/hello.hgs +4 -19
- package/examples/math-library.hgs +1 -2
- package/examples/scores.hgs +0 -1
- package/examples/statistics-ui.hgs +0 -1
- package/examples/statistics.hgs +0 -1
- package/examples/text-ui.hgs +0 -1
- package/examples/text.hgs +0 -1
- package/package.json +21 -5
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# React·Vue에서 한글스크립트 사용하기
|
|
2
|
+
|
|
3
|
+
이 가이드는 `@uiwwsw/hangulscript@0.7.0` 문법과 공통 Vite 플러그인을 사용합니다.
|
|
4
|
+
화면과 상태는 React/Vue로 만들고 계산·조건·검증 함수를 `.hgs`에 작성합니다.
|
|
5
|
+
데모의 `숫자입력`·`버튼`·`보여주기`는 데모 UI 실행 환경의 API이며 React/Vue 컴포넌트로 자동 변환되지 않습니다.
|
|
6
|
+
|
|
7
|
+
## 완성된 예제를 먼저 실행하기
|
|
8
|
+
|
|
9
|
+
Node.js 24에서 검증했습니다. 예제의 Vite는 Node.js `^20.19.0 || >=22.12.0`을 요구합니다.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
git clone https://github.com/uiwwsw/hangulscript.git
|
|
13
|
+
cd hangulscript/examples/react-vite
|
|
14
|
+
npm ci
|
|
15
|
+
npm run dev
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Vue는 같은 저장소의 `examples/vue-vite`에서 `npm ci`와 `npm run dev`를 실행하세요.
|
|
19
|
+
터미널에 표시된 localhost 주소를 열고 가격 10000, 할인율 20을 입력한 뒤 **계산하기**를 누르면 결제 금액 8,000원이 표시됩니다.
|
|
20
|
+
개발 서버는 loopback에서 실행하며, 포트가 사용 중이면 터미널에 표시된 실제 주소를 사용하세요.
|
|
21
|
+
배포할 정적 파일은 각 예제에서 `npm run build`로 만들고 `npm run preview`로 확인합니다.
|
|
22
|
+
|
|
23
|
+
- [React 전체 소스](../examples/react-vite)
|
|
24
|
+
- [Vue 전체 소스](../examples/vue-vite)
|
|
25
|
+
|
|
26
|
+
## 기존 Vite 프로젝트에 설치하기
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install --save-dev @uiwwsw/hangulscript@^0.7.0
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
React/Vue와 해당 Vite 플러그인은 기존 프로젝트에 설치돼 있다고 가정합니다.
|
|
33
|
+
새 프로젝트는 위의 완성된 예제를 사용할 수 있습니다.
|
|
34
|
+
|
|
35
|
+
React의 `vite.config.js`:
|
|
36
|
+
|
|
37
|
+
```js
|
|
38
|
+
import { defineConfig } from 'vite';
|
|
39
|
+
import react from '@vitejs/plugin-react';
|
|
40
|
+
import hangulscript from '@uiwwsw/hangulscript/vite';
|
|
41
|
+
|
|
42
|
+
export default defineConfig({ plugins: [hangulscript(), react()] });
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Vue의 `vite.config.js`:
|
|
46
|
+
|
|
47
|
+
```js
|
|
48
|
+
import { defineConfig } from 'vite';
|
|
49
|
+
import vue from '@vitejs/plugin-vue';
|
|
50
|
+
import hangulscript from '@uiwwsw/hangulscript/vite';
|
|
51
|
+
|
|
52
|
+
export default defineConfig({ plugins: [hangulscript(), vue()] });
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## 공통 로직 작성하기
|
|
56
|
+
|
|
57
|
+
두 예제의 `src/discount.hgs`는 동일합니다. 함수와 조건을 한글 문장으로 작성하고 ESM `export`로 내보냅니다.
|
|
58
|
+
|
|
59
|
+
```text
|
|
60
|
+
결제금액(가격: 숫자, 할인율: 숫자)를 정의한다:
|
|
61
|
+
만약 !Number.isFinite(가격) || !Number.isFinite(할인율) || 가격 < 0 || 할인율 < 0 || 할인율 > 100 이라면:
|
|
62
|
+
돌려주기 "가격은 0 이상, 할인율은 0~100 사이로 입력하세요"
|
|
63
|
+
돌려주기 가격 - 반올림(가격 * 할인율 / 100)
|
|
64
|
+
|
|
65
|
+
결제금액을 공개한다
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## React에서 호출하기
|
|
69
|
+
|
|
70
|
+
`src/main.jsx`에서 함수를 가져와 submit 이벤트에 연결합니다. 입력과 결과 상태는 React가 관리합니다.
|
|
71
|
+
|
|
72
|
+
```jsx
|
|
73
|
+
import { useState } from 'react';
|
|
74
|
+
import { createRoot } from 'react-dom/client';
|
|
75
|
+
import { 결제금액 } from './discount.hgs';
|
|
76
|
+
import './style.css';
|
|
77
|
+
|
|
78
|
+
function App() {
|
|
79
|
+
const [가격, 가격변경] = useState('10000');
|
|
80
|
+
const [할인율, 할인율변경] = useState('20');
|
|
81
|
+
const [결과, 결과변경] = useState(null);
|
|
82
|
+
function 계산(event) {
|
|
83
|
+
event.preventDefault();
|
|
84
|
+
결과변경(결제금액(Number(가격), Number(할인율)));
|
|
85
|
+
}
|
|
86
|
+
return <main>
|
|
87
|
+
<h1>React + 한글스크립트</h1>
|
|
88
|
+
<p>화면은 React, 계산과 검증은 discount.hgs에서 처리합니다.</p>
|
|
89
|
+
<form onSubmit={계산}>
|
|
90
|
+
<label>가격 (원)<input type="number" min="0" required value={가격} onChange={e => 가격변경(e.target.value)} /></label>
|
|
91
|
+
<label>할인율 (%)<input type="number" min="0" max="100" step="any" required value={할인율} onChange={e => 할인율변경(e.target.value)} /></label>
|
|
92
|
+
<button type="submit">계산하기</button>
|
|
93
|
+
</form>
|
|
94
|
+
<output aria-live="polite">{결과 === null ? '입력 후 계산하기를 눌러 주세요.' : typeof 결과 === 'number' ? `결제 금액: ${결과.toLocaleString('ko-KR')}원` : 결과}</output>
|
|
95
|
+
</main>;
|
|
96
|
+
}
|
|
97
|
+
createRoot(document.getElementById('app')).render(<App />);
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Vue에서 호출하기
|
|
101
|
+
|
|
102
|
+
`src/App.vue`에서 같은 함수를 가져와 submit 이벤트에 연결합니다. 반응형 상태는 Vue가 관리합니다.
|
|
103
|
+
|
|
104
|
+
```vue
|
|
105
|
+
<script setup>
|
|
106
|
+
import { ref } from 'vue';
|
|
107
|
+
import { 결제금액 } from './discount.hgs';
|
|
108
|
+
const 가격 = ref(10000);
|
|
109
|
+
const 할인율 = ref(20);
|
|
110
|
+
const 결과 = ref(null);
|
|
111
|
+
function 계산() {
|
|
112
|
+
결과.value = 결제금액(Number(가격.value), Number(할인율.value));
|
|
113
|
+
}
|
|
114
|
+
</script>
|
|
115
|
+
|
|
116
|
+
<template>
|
|
117
|
+
<main>
|
|
118
|
+
<h1>Vue + 한글스크립트</h1>
|
|
119
|
+
<p>화면은 Vue, 계산과 검증은 discount.hgs에서 처리합니다.</p>
|
|
120
|
+
<form @submit.prevent="계산">
|
|
121
|
+
<label>가격 (원)<input v-model="가격" type="number" min="0" required /></label>
|
|
122
|
+
<label>할인율 (%)<input v-model="할인율" type="number" min="0" max="100" step="any" required /></label>
|
|
123
|
+
<button type="submit">계산하기</button>
|
|
124
|
+
</form>
|
|
125
|
+
<output aria-live="polite">{{ 결과 === null ? '입력 후 계산하기를 눌러 주세요.' : typeof 결과 === 'number' ? `결제 금액: ${결과.toLocaleString('ko-KR')}원` : 결과 }}</output>
|
|
126
|
+
</main>
|
|
127
|
+
</template>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## TypeScript 프로젝트와 빌드 범위
|
|
131
|
+
|
|
132
|
+
| 방식 | 제공 범위 | 적합한 용도 |
|
|
133
|
+
| --- | --- | --- |
|
|
134
|
+
| Vite 플러그인으로 `.hgs` import | JavaScript 변환, Vite 개발 서버·빌드 연동 | React/Vue JavaScript 프로젝트 |
|
|
135
|
+
| `ksc build` 후 `.js` import | 타입 검사, JavaScript와 `.d.ts` 생성 | TypeScript 프로젝트·라이브러리 |
|
|
136
|
+
| 온라인 데모의 화면 함수 | 격리 실행, 입력창·버튼·결과 카드 | 설치 없는 도구 만들기·코드 공유 |
|
|
137
|
+
|
|
138
|
+
0.7.0부터 Vite 플러그인은 구문과 타입을 검사하고 오류가 있으면 빌드를 중단합니다. 선언 생성·디버깅용 원본 `.hgs` 소스맵은 제공하지 않습니다.
|
|
139
|
+
TypeScript에서 `.hgs` 파일을 직접 가져오면 모듈 타입을 찾지 못할 수 있습니다.
|
|
140
|
+
외부 TypeScript 소비자에게 선언을 제공하려면 다음처럼 빌드한 `.js`를 가져오세요. 인접한 `.d.ts`를 TypeScript가 읽습니다.
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
npx ksc build src/discount.hgs
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
import { 결제금액 } from './discount.js';
|
|
148
|
+
const 결과 = 결제금액(10000, 20); // number | string
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
이 방식은 `.hgs`를 수정할 때 다시 빌드해야 합니다. 명시적인 타입과 추론 가능한 값은 검사하며, `any` 값에 대한 검사는 제한됩니다.
|
|
152
|
+
Next.js·Webpack처럼 Vite를 사용하지 않는 환경에서도 미리 만든 `.js`·`.d.ts`를 가져오는 방식을 사용할 수 있습니다. 전용 Next.js·Webpack 플러그인은 제공하지 않습니다.
|
package/docs/support.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# 지원 범위와 호환성
|
|
2
|
+
|
|
3
|
+
한글스크립트는 명시된 한국어 문법을 JavaScript ES 모듈로 컴파일합니다. 임의의 자연어를 추측하지 않으며 별도 시작 표기는 사용하지 않습니다. 이 문서는 0.7.0 언어 패키지와 0.2.0 VS Code 확장의 지원 계약입니다.
|
|
4
|
+
|
|
5
|
+
| 환경 | 지원 내용 | 검증 |
|
|
6
|
+
| --- | --- | --- |
|
|
7
|
+
| Node.js 20.19 이상 | `ksc run`, JS + `.d.ts` 빌드, `.hgs` 모듈 import | Node 22·24 CI, 실행 통합 테스트 |
|
|
8
|
+
| React·Vue + Vite | `.hgs` import, 개발·프로덕션 타입 오류 차단 | React JSX·Vue SFC 예제 빌드 |
|
|
9
|
+
| VS Code 데스크톱 1.90 이상 | 문법 강조, 들여쓰기, 포맷, 진단, 타입 정보, 정의로 이동, 스코프 자동 완성 | 실제 Extension Host 통합 테스트 |
|
|
10
|
+
| 웹 데모 | 타입 검사, 격리 실행, 입력·버튼 UI, 공유 | 별도 브라우저 검사기 테스트 |
|
|
11
|
+
| JavaScript·TypeScript 소비자 | 생성된 `.js`와 `.d.ts` import | ESM 실행·선언 생성 테스트 |
|
|
12
|
+
|
|
13
|
+
## Node에서 사용하기
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @uiwwsw/hangulscript@^0.7.0
|
|
17
|
+
npx ksc run src/main.hgs
|
|
18
|
+
# 또는 Node의 등록 진입점으로 직접 로드
|
|
19
|
+
node --import @uiwwsw/hangulscript/register src/main.hgs
|
|
20
|
+
# 배포 파일 생성
|
|
21
|
+
npx ksc build src/main.hgs --out-dir dist
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`ksc run`과 Node 등록 진입점은 `.hgs` 상대 import를 직접 읽고 검사합니다. 소스 옆에 생성물을 남기지 않습니다. 일반 Node 코드와 마찬가지로 파일·네트워크 권한을 가지므로 신뢰하는 코드에 사용하세요.
|
|
25
|
+
|
|
26
|
+
`ksc build`는 진입 파일과 그 폴더 아래의 `.hgs` 의존성을 함께 빌드하고 디렉터리 구조를 유지합니다. `.hgs` import는 `.js`로 바뀝니다. 진입 폴더 밖의 HGS 의존성은 오류로 처리하므로 공통 상위 폴더에 진입 파일을 두세요. 생성된 `.js`는 ESM이므로 소비 프로젝트 `package.json`에 `"type": "module"`을 설정하세요.
|
|
27
|
+
|
|
28
|
+
Vite가 아닌 환경에서 `.hgs` 파일을 바로 가져오려면 해당 로더가 필요합니다. 미리 생성한 `.js`·`.d.ts`는 일반 JS/TS 모듈로 사용할 수 있습니다. 상대 경로의 기존 JavaScript 파일·정적 자산은 HGS 빌드가 복사하지 않습니다.
|
|
29
|
+
|
|
30
|
+
## 타입과 오류
|
|
31
|
+
|
|
32
|
+
기본 검사는 strict 모드입니다. 가장 가까운 `tsconfig.json`의 `compilerOptions`와 `extends`를 읽습니다. 타입 해석을 위한 `types`, `typeRoots`, `paths`, `lib` 등을 사용할 수 있습니다. Node API 타입이 필요하면 프로젝트에 `@types/node`를 설치하고 `compilerOptions.types`에 `"node"`를 추가하세요. 파일 선택은 HGS 진입 파일과 import 그래프로 결정됩니다. 출력 형식은 ESM/ES2022, JS + 선언으로 고정하며 `noEmit`, `outDir` 등 출력 옵션은 CLI 설정이 우선합니다.
|
|
33
|
+
|
|
34
|
+
함수 매개변수에 타입을 적으면 잘못된 인자 타입·개수·존재하지 않는 속성을 검사합니다. `any`를 지정한 값은 엄격한 검사를 우회합니다. 외부 JavaScript 모듈은 대응하는 타입 선언이 있어야 정확히 검사됩니다. 브라우저 데모는 로컬 tsconfig·Node API·외부 모듈을 읽지 않습니다.
|
|
35
|
+
|
|
36
|
+
진단은 원본 HGS 행과 UTF-16 열을 사용합니다. 변환 과정에서 새로 생긴 토큰의 정확한 열을 찾을 수 없으면 해당 문장의 시작 위치를 사용합니다. 디버거용 소스맵과 실행 중 스택 추적의 원본 위치 변환은 아직 제공하지 않습니다.
|
|
37
|
+
|
|
38
|
+
## 편집기 기능과 배포
|
|
39
|
+
|
|
40
|
+
[VS Code 설치 및 기능 안내](../extensions/vscode/README.md)를 참고하세요. 확장은 컴파일러와 같은 저장소에서 관리하며 독립 버전으로 배포합니다. 편집기 검사는 Worker에서 실행하며 사용자 코드는 실행하지 않습니다. 자동 완성은 스코프의 이름과 스니펫을 제공합니다. 전체 속성 자동 완성, 자동 import, 이름 변경, 디버거, vscode.dev는 아직 지원하지 않습니다.
|
|
41
|
+
|
|
42
|
+
0.x에서는 문법의 호환성을 깨는 변경을 minor 버전에서만 진행하고 변경 내역·마이그레이션을 안내합니다. patch 버전은 호환되는 수정에 사용합니다. 1.0은 별도의 문법 동결과 호환성 검증을 거쳐 결정합니다. 사용자용 확장을 Marketplace에 게시하는 것과 Microsoft가 기본 내장 언어로 채택하는 것은 별개입니다.
|
package/examples/calculator.hgs
CHANGED
package/examples/discount-ui.hgs
CHANGED
package/examples/discount.hgs
CHANGED
package/examples/hello.hgs
CHANGED
|
@@ -1,21 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
변수 나이: 숫자 = 12;
|
|
1
|
+
이름은 "세상"이다
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
3
|
+
인사(누구: 문자열)를 정의한다:
|
|
4
|
+
돌려주기 "안녕, " + 누구 + "!"
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
이름: 문자열;
|
|
10
|
-
나이: 숫자;
|
|
11
|
-
생성자(이름: 문자열, 나이: 숫자) {
|
|
12
|
-
이것.이름 = 이름;
|
|
13
|
-
이것.나이 = 나이;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
함수 소개(): 문자열 {
|
|
17
|
-
반환 `${이것.이름}(${이것.나이}) 입니다`;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
콘솔.출력(인사(이름));
|
|
6
|
+
출력(인사(이름))
|
package/examples/scores.hgs
CHANGED
package/examples/statistics.hgs
CHANGED
package/examples/text-ui.hgs
CHANGED
package/examples/text.hgs
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uiwwsw/hangulscript",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "한글 문장으로 작성하고 JavaScript와 타입 선언으로 배포하는
|
|
3
|
+
"version": "0.7.0",
|
|
4
|
+
"description": "한글 문장으로 작성하고 JavaScript와 타입 선언으로 배포하는 프로그래밍 언어",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.js",
|
|
@@ -17,6 +17,15 @@
|
|
|
17
17
|
"./vite": {
|
|
18
18
|
"types": "./dist/vite.d.ts",
|
|
19
19
|
"import": "./dist/vite.js"
|
|
20
|
+
},
|
|
21
|
+
"./formatter": {
|
|
22
|
+
"types": "./dist/formatter.d.ts",
|
|
23
|
+
"import": "./dist/formatter.js"
|
|
24
|
+
},
|
|
25
|
+
"./register": "./dist/register.js",
|
|
26
|
+
"./editor": {
|
|
27
|
+
"types": "./dist/editor.d.ts",
|
|
28
|
+
"import": "./dist/editor.js"
|
|
20
29
|
}
|
|
21
30
|
},
|
|
22
31
|
"bin": {
|
|
@@ -27,14 +36,19 @@
|
|
|
27
36
|
"README.md",
|
|
28
37
|
"LANGUAGE.md",
|
|
29
38
|
"LICENSE",
|
|
30
|
-
"examples/*.hgs"
|
|
39
|
+
"examples/*.hgs",
|
|
40
|
+
"docs",
|
|
41
|
+
"CHANGELOG.md"
|
|
31
42
|
],
|
|
32
43
|
"scripts": {
|
|
33
44
|
"build": "node ./scripts/build.js",
|
|
34
45
|
"prepublishOnly": "npm test && npm run build",
|
|
35
46
|
"test": "node --test",
|
|
36
47
|
"build:site": "node scripts/build-site.js",
|
|
37
|
-
"benchmark": "node scripts/benchmark.js"
|
|
48
|
+
"benchmark": "node scripts/benchmark.js",
|
|
49
|
+
"build:vscode": "node scripts/build-vscode.js",
|
|
50
|
+
"package:vscode": "npm run build:vscode && cd extensions/vscode && vsce package --no-dependencies",
|
|
51
|
+
"test:vscode": "npm run build:vscode && node scripts/run-editor-qa.js"
|
|
38
52
|
},
|
|
39
53
|
"dependencies": {
|
|
40
54
|
"typescript": "^5.4.0"
|
|
@@ -55,12 +69,14 @@
|
|
|
55
69
|
},
|
|
56
70
|
"homepage": "https://github.com/uiwwsw/hangulscript#readme",
|
|
57
71
|
"engines": {
|
|
58
|
-
"node": ">=20"
|
|
72
|
+
"node": ">=20.19.0"
|
|
59
73
|
},
|
|
60
74
|
"publishConfig": {
|
|
61
75
|
"access": "public"
|
|
62
76
|
},
|
|
63
77
|
"devDependencies": {
|
|
78
|
+
"@vscode/test-electron": "^3.1.0",
|
|
79
|
+
"@vscode/vsce": "^4.0.0",
|
|
64
80
|
"esbuild": "^0.25.0"
|
|
65
81
|
},
|
|
66
82
|
"types": "dist/index.d.ts"
|