├── .DS_Store
├── .all-contributorsrc
├── LICENSE
├── README.md
├── examples
├── 99bears.umm
├── addition_calculator.umm
├── evenodd.umm
├── factorial_calculator.umm
├── gugudan.umm
├── helloworld.umm
├── pyramid.umm
├── sqrt.umm
├── string_test.umm
└── tree.umm
├── setup.py
├── umjunsik-lang-cc
├── .gitignore
├── Makefile
└── src
│ ├── file.c
│ ├── file.h
│ ├── info.h
│ ├── main.c
│ ├── parse.c
│ ├── parse.h
│ ├── string.c
│ └── string.h
├── umjunsik-lang-csharp
├── .gitignore
├── Program.cs
├── umjunsik-lang-csharp.csproj
└── umjunsik-lang-csharp.sln
├── umjunsik-lang-deno
├── index.ts
└── readme.md
├── umjunsik-lang-go
├── ast
│ └── ast.go
├── eval
│ ├── eval.go
│ └── util.go
├── go.mod
├── lexer
│ └── lexer.go
├── main.go
├── object
│ └── object.go
├── parser
│ ├── parser.go
│ └── util.go
└── token
│ └── token.go
├── umjunsik-lang-java
├── .DS_Store
├── main.java
└── setting
│ ├── .DS_Store
│ ├── Count.java
│ ├── Items.java
│ ├── console
│ ├── ChangeUni.java
│ ├── Print.java
│ └── Scan.java
│ └── var
│ ├── VarGet.java
│ └── VarSet.java
├── umjunsik-lang-kotlin
├── build.gradle.kts
├── gradle.properties
├── settings.gradle.kts
└── src
│ └── main
│ └── kotlin
│ └── com
│ └── alphagot
│ └── kumjunsiklang
│ ├── Main.kt
│ └── ParseUtils.kt
├── umjunsik-lang-node
├── .gitignore
├── package.json
├── src
│ └── index.ts
├── tsconfig.json
└── yarn.lock
├── umjunsik-lang-python
├── __init__.py
├── __main__.py
└── runtime.py
├── umjunsik-lang-rust
├── .gitignore
├── Cargo.toml
├── README.md
├── compiler
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── interpreter
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
└── lib
│ ├── Cargo.toml
│ └── src
│ ├── ast.rs
│ ├── lib.rs
│ └── parser.rs
├── umjunsik-lang-vba
├── Module1.vb
├── README.md
├── Sheet1.vb
├── ThisWorkbook.vb
└── interpreter.xlsm
└── umjunsik-lang-web
├── index.html
└── src
├── main.css
├── main.js
└── vendors
└── pico
├── pico.min.css
└── pico.min.css.map
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rycont/umjunsik-lang/e973f9d22b9803ee86b53d8e60f1b65ab08c7547/.DS_Store
--------------------------------------------------------------------------------
/.all-contributorsrc:
--------------------------------------------------------------------------------
1 | {
2 | "files": [
3 | "README.md"
4 | ],
5 | "imageSize": 100,
6 | "commit": false,
7 | "contributors": [
8 | {
9 | "login": "cstria0106",
10 | "name": "goorm",
11 | "avatar_url": "https://avatars1.githubusercontent.com/u/11474150?v=4",
12 | "profile": "https://github.com/cstria0106",
13 | "contributions": [
14 | "platform"
15 | ]
16 | },
17 | {
18 | "login": "pl-Steve28-lq",
19 | "name": "Steve28",
20 | "avatar_url": "https://avatars2.githubusercontent.com/u/64412954?v=4",
21 | "profile": "https://github.com/pl-Steve28-lq",
22 | "contributions": [
23 | "platform"
24 | ]
25 | },
26 | {
27 | "login": "pmh-only",
28 | "name": "PMH",
29 | "avatar_url": "https://avatars2.githubusercontent.com/u/39158228?v=4",
30 | "profile": "https://trinets.xyz",
31 | "contributions": [
32 | "platform"
33 | ]
34 | },
35 | {
36 | "login": "AkiaCode",
37 | "name": "Aki",
38 | "avatar_url": "https://avatars0.githubusercontent.com/u/71239005?v=4",
39 | "profile": "https://github.com/AkiaCode",
40 | "contributions": [
41 | "code"
42 | ]
43 | },
44 | {
45 | "login": "Tim232",
46 | "name": "Tim232",
47 | "avatar_url": "https://avatars1.githubusercontent.com/u/64291996?v=4",
48 | "profile": "https://info.tim23.me",
49 | "contributions": [
50 | "code"
51 | ]
52 | },
53 | {
54 | "login": "Ign0reLee",
55 | "name": "JeYoung",
56 | "avatar_url": "https://avatars.githubusercontent.com/u/46403849?v=4",
57 | "profile": "https://github.com/Ign0reLee",
58 | "contributions": [
59 | "code"
60 | ]
61 | },
62 | {
63 | "login": "Rokr0k",
64 | "name": "Rok",
65 | "avatar_url": "https://avatars.githubusercontent.com/u/35794170?v=4",
66 | "profile": "http://rokr0k.tk",
67 | "contributions": [
68 | "platform"
69 | ]
70 | },
71 | {
72 | "login": "adp-study",
73 | "name": "adp-study",
74 | "avatar_url": "https://avatars.githubusercontent.com/u/59760424?v=4",
75 | "profile": "https://github.com/adp-study",
76 | "contributions": [
77 | "infra",
78 | "bug"
79 | ]
80 | },
81 | {
82 | "login": "noname0310",
83 | "name": "noname",
84 | "avatar_url": "https://avatars.githubusercontent.com/u/48761044?v=4",
85 | "profile": "https://www.youtube.com/c/noname0310",
86 | "contributions": [
87 | "code"
88 | ]
89 | },
90 | {
91 | "login": "TralocDheckoa",
92 | "name": "TralocDheckoa",
93 | "avatar_url": "https://avatars.githubusercontent.com/u/42158095?v=4",
94 | "profile": "https://github.com/TralocDheckoa",
95 | "contributions": [
96 | "code"
97 | ]
98 | },
99 | {
100 | "login": "sangchoo1201",
101 | "name": "sangchoo1201",
102 | "avatar_url": "https://avatars.githubusercontent.com/u/75765800?v=4",
103 | "profile": "https://github.com/sangchoo1201",
104 | "contributions": [
105 | "bug"
106 | ]
107 | },
108 | {
109 | "login": "shs3182ym",
110 | "name": "Sukuna Shinmyoumaru",
111 | "avatar_url": "https://avatars.githubusercontent.com/u/56759376?v=4",
112 | "profile": "http://warning.or.kr",
113 | "contributions": [
114 | "platform"
115 | ]
116 | },
117 | {
118 | "login": "alvin1007",
119 | "name": "Yeong Jae Cho",
120 | "avatar_url": "https://avatars.githubusercontent.com/u/77112874?v=4",
121 | "profile": "https://github.com/alvin1007",
122 | "contributions": [
123 | "platform"
124 | ]
125 | },
126 | {
127 | "login": "kiwiyou",
128 | "name": "kiwiyou",
129 | "avatar_url": "https://avatars.githubusercontent.com/u/12986388?v=4",
130 | "profile": "http://kiwiyou.dev",
131 | "contributions": [
132 | "platform"
133 | ]
134 | },
135 | {
136 | "login": "kyle-seongwoo-jun",
137 | "name": "Kyle Seongwoo Jun",
138 | "avatar_url": "https://avatars.githubusercontent.com/u/16515307?v=4",
139 | "profile": "https://seongxwoo.notion.site/Kyle-b49a1520f7ea4d5a86acedcf201129f6",
140 | "contributions": [
141 | "infra"
142 | ]
143 | },
144 | {
145 | "login": "sean9892",
146 | "name": "Yubin Choi",
147 | "avatar_url": "https://avatars.githubusercontent.com/u/46587635?v=4",
148 | "profile": "https://github.com/sean9892",
149 | "contributions": [
150 | "example"
151 | ]
152 | },
153 | {
154 | "login": "Baekjoon",
155 | "name": "Baekjoon Choi",
156 | "avatar_url": "https://avatars.githubusercontent.com/u/706317?v=4",
157 | "profile": "https://www.acmicpc.net",
158 | "contributions": [
159 | "infra"
160 | ]
161 | },
162 | {
163 | "login": "EGGnmad",
164 | "name": "ㅇㅂㅎ",
165 | "avatar_url": "https://avatars.githubusercontent.com/u/93484785?v=4",
166 | "profile": "https://eggnmad.com/info/",
167 | "contributions": [
168 | "example"
169 | ]
170 | },
171 | {
172 | "login": "pizzaroot",
173 | "name": "pizzaroot",
174 | "avatar_url": "https://avatars.githubusercontent.com/u/17989599?v=4",
175 | "profile": "https://github.com/pizzaroot",
176 | "contributions": [
177 | "platform"
178 | ]
179 | },
180 | {
181 | "login": "depth221",
182 | "name": "Dongha Hwang",
183 | "avatar_url": "https://avatars.githubusercontent.com/u/22697167?v=4",
184 | "profile": "https://luxurycoop.tistory.com/",
185 | "contributions": [
186 | "example",
187 | "bug"
188 | ]
189 | },
190 | {
191 | "login": "PersesTitan",
192 | "name": "PersesTitan",
193 | "avatar_url": "https://avatars.githubusercontent.com/u/97427878?v=4",
194 | "profile": "https://github.com/PersesTitan",
195 | "contributions": [
196 | "platform",
197 | "bug"
198 | ]
199 | },
200 | {
201 | "login": "kongchu2",
202 | "name": "JunHyeok Hong",
203 | "avatar_url": "https://avatars.githubusercontent.com/u/48686444?v=4",
204 | "profile": "http://codeup.kr/userinfo.php?user=qwerty5233",
205 | "contributions": [
206 | "doc"
207 | ]
208 | },
209 | {
210 | "login": "happy-spark",
211 | "name": "happy-spark",
212 | "avatar_url": "https://avatars.githubusercontent.com/u/107300540?v=4",
213 | "profile": "https://github.com/happy-spark",
214 | "contributions": [
215 | "example"
216 | ]
217 | },
218 | {
219 | "login": "kms0219kms",
220 | "name": "Minsu Kim",
221 | "avatar_url": "https://avatars.githubusercontent.com/u/67222970?v=4",
222 | "profile": "https://sskate.me",
223 | "contributions": [
224 | "platform",
225 | "design"
226 | ]
227 | },
228 | {
229 | "login": "jerryjungwh",
230 | "name": "JerryJung",
231 | "avatar_url": "https://avatars.githubusercontent.com/u/16649567?v=4",
232 | "profile": "https://www.youtube.com/@comgongbro",
233 | "contributions": [
234 | "doc"
235 | ]
236 | },
237 | {
238 | "login": "Hiyabye",
239 | "name": "Jihoon Lee",
240 | "avatar_url": "https://avatars.githubusercontent.com/u/50550999?v=4",
241 | "profile": "https://github.com/Hiyabye",
242 | "contributions": [
243 | "doc"
244 | ]
245 | }
246 | ],
247 | "contributorsPerLine": 7,
248 | "projectName": "umjunsik-lang",
249 | "projectOwner": "rycont",
250 | "repoType": "github",
251 | "repoHost": "https://github.com",
252 | "skipCi": true,
253 | "commitConvention": "angular",
254 | "commitType": "docs"
255 | }
256 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 rycont
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 엄랭
2 |
3 | 엄랭은 세계 최초의 인물이름으로 만들어진 난해한 프로그래밍 언어입니다. 엄준식이 어떻게 인물 이름이냐고요? 그러게요ㅋㅋ 어떻게 엄준식이 어떻게 사람 이름이지ㅋㅋ "엄준식 사람이름인데요"
4 |
5 | > 어디선가 유입이 자꾸 들어오고 있는것같은데.. 혹시 시간 되신다면 어디쪽 링크 통해서 들어오셨는지 기재 부탁드리겠습니다. [어떻게 엄랭을 발견하셨나요..!](https://github.com/rycont/umjunsik-lang/issues/1)
6 |
7 | 
8 |
9 |
10 | ```
11 | 어떻게
12 |
13 | 엄식?
14 | 어엄식?
15 |
16 | 동탄어?준... ....
17 |
18 | 엄어,
19 | 어엄어어.
20 |
21 | 준.. ...
22 | 식어어!
23 |
24 | 이 사람이름이냐ㅋㅋ
25 | ```
26 |
27 | [cjaewon/umlang](https://github.com/cjaewon/umlang)에 영감을 받아 제작되었습니다
28 |
29 | **주의: Umlang 표기는 위의 프로젝트와 겹치기 때문에, 꼭 한글로만 표기해주세요.**
30 | 영문표기를 해야할때는 "umjunsik-lang"이라고 표기해주세요.
31 |
32 | ## 엄 on Live!
33 | - 코딩애플: [엄준식 프로그래밍 언어 (어떤 놈이 만들었냐)](https://www.youtube.com/watch?v=G0psQ54f5zE)
34 | - 컴공선배: [엄랭 어떤 놈이 만들었냐? 어떤 놈 만났습니다.](https://youtu.be/NS56sb6EYIw)
35 | - 코딩애플: [chatGPT는 엄준식 프로그래밍 언어도 잘할까?](https://www.youtube.com/watch?v=SdDs0ScOFSU)
36 |
37 | # 구현체
38 | + [류갓 WebIDE에서 엄랭을 실행할 수 있습니다](https://www.ryugod.com/)
39 |
40 | - [디노 (v2)](https://github.com/rycont/umjunsik-lang/tree/master/umjunsik-lang-deno) : 레퍼런스 런타임입니다
41 | - [노드JS (v2)](https://github.com/rycont/umjunsik-lang/tree/master/umjunsik-lang-node) : Deno 구현체의 NodeJS 포트버전입니다.
42 | - [파이썬 (v2)](https://github.com/rycont/umjunsik-lang/tree/master/umjunsik-lang-python)
43 | - pip에서 `umjunsik` 패키지를 설치할 수 있습니다
44 | - `$ pip install umjunsik && umjunsik [filename.umm]`
45 | - [웹-엄 (v2)](https://github.com/rycont/umjunsik-lang/tree/master/umjunsik-lang-web) : [kms0219kms](https://github.com/kms0219kms)님이 [호스팅해주시고 있습니다🎉](https://umjunsik-lang.devayaan.me/)
46 | - [C (v2)](https://github.com/rycont/umjunsik-lang/tree/master/umjunsik-lang-cc)
47 | - [C# (v2)](https://github.com/rycont/umjunsik-lang/tree/master/umjunsik-lang-csharp)
48 | - [코틀린 (v2)](https://github.com/rycont/umjunsik-lang/tree/master/umjunsik-lang-kotlin)
49 | - [Go (v2)](https://github.com/rycont/umjunsik-lang/tree/master/umjunsik-lang-go) : 실제 인터프리터 구조를 차용하여 개발한 고급 런타임입니다
50 | - [러스트 (v2)](https://github.com/rycont/umjunsik-lang/tree/master/umjunsik-lang-rust)
51 |
52 |
53 | # Contributors ✨
54 |
55 | [](#contributors-)
56 |
57 |
58 |
59 |
60 |
61 |
99 |
100 |
101 |
102 |
103 |
104 |
105 | # 문법
106 |
107 | 엄랭은 "엄", "준", "식", "동탄" 네개의 키워드와 "!", ".", " ", "~", "ㅋ" 다섯개의 기호로 코드가 이루어집니다.
108 | 모든 프로그램은 "어떻게"로 시작하며, 항상 "이 사람이름이냐ㅋㅋ"로 끝나야 합니다.
109 |
110 | ## 자료형
111 |
112 | 정수: 온점, 반점의 갯수로 나타냅니다. 온점의 갯수만큼 1을 더하며, 반점의 갯수만큼 1을 뺍니다.
113 |
114 | ```
115 | ... => 3
116 | .. => 2
117 | ,, => -2
118 | ,,, => -3
119 | .,., => 0
120 | ```
121 |
122 | ## 연산자
123 |
124 | - 1 증가: `.`
125 | - 1 감소: `,`
126 | - 곱하기: " "(공백)
127 |
128 | ```
129 | .. -> 2
130 | ,, -> -2
131 | ., -> 0
132 | .. .. -> 4
133 | .. ,, -> -4
134 | ... ... ... -> 27
135 | ```
136 |
137 | ## 변수
138 |
139 | 변수는 인덱싱(정수)을 통해 접근하고 대입할 수 있습니다. 지정하지 않았을경우 모든 변수의 기본값은 0입니다.
140 |
141 | ### 대입(엄)
142 |
143 | 연음의 갯수번째 변수에 뒤에 오는 수를 대입합니다
144 |
145 | ```
146 | 어어엄 => 3번째 변수에 0 지정
147 | 어엄 => 2번째 변수에 0 지정
148 | 엄.. => 1번째 변수에 2 지정
149 | 어엄. => 2번째 변수에 1 지정
150 | 엄,,, => 1번째 변수에 -3 지정
151 | ```
152 |
153 | ### 사용(어)
154 |
155 | 연음의 갯수번째 변수를 불러옵니다
156 |
157 | ```
158 | 어 => 1번째 변수
159 | 어어 => 2번째 변수
160 | 어어어 => 3번째 변수
161 | ```
162 |
163 | ### 초안/미구현 : N번째 변수에 대입 (엌ㅋ)
164 |
165 | `엌`과 `ㅋ` 사이에 입력된 수 번째의 변수에 뒤에 오는 수를 대입합니다. 시작하는 엌은 `엌ㅋㅋㅋㅋㅋㅋㅋㅋ` 등으로, 끝내는 ㅋ는 `ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ` 등으로 늘려서 적을 수 있으며, 이에 따른 동작의 변화는 없습니다.
166 |
167 | ```
168 | 엌..ㅋ => 2번째 변수에 0 지정
169 | 엌ㅋㅋㅋㅋㅋ..ㅋㅋㅋㅋㅋ. => 2번째 변수에 1 지정
170 | 엌.ㅋ어 => 1번쨰 변수에 `어`값 지정
171 | 엌어ㅋ어어 => `어`번째 변수에 `어어` 변수의 값 지정
172 | ```
173 |
174 | ### 초안/미구현 : N번쨰 변수 가져오기
175 |
176 | `어`와 `ㅋ` 사이에 입력된 수 번째의 변수의 값을 가져옵니다. 만약 마지막 문자가 `ㅋ`이 아니라 `엌`이라면 `어ㅋ`으로 분해해서 평가합니다. 끝내는 ㅋ은 `ㅋㅋㅋㅋㅋ`등으로 늘려서 적을 수 있으며, 이에 따른 동작의 변화는 없습니다.
177 |
178 | ```
179 | 어..ㅋ => 2번째 변수
180 | 어,,,ㅋ => -3번째 변수
181 | 어엌 => 어어ㅋ => `어`번째 변수
182 | 어어어,,ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ => (어어 - 2)번째 변수
183 | ```
184 | ### 초안/미구현 : 변수연산
185 |
186 | 변수 / 상수 덧셈식 뒤에 변수를 이어적으면 뒤에 따르는 변수를 더할 수 있습니다. 사칙연산의 우선순위가 적용되지 않으며, 무조건 왼쪽에서부터 연산합니다.
187 |
188 | ```
189 | 어, 어어 => 어 - 1 * 어어 => 어 - 어어
190 | 어.어어 => 어 + 1 + 어어
191 | 어어. 어어 => 어어 + 1 * 어어 => 어어 + 어어
192 | 어어 어어 어어 => 어어 ^ 3
193 | ```
194 |
195 | ~~정신나갈것같아요~~
196 |
197 | ## 콘솔
198 |
199 | ### 식?
200 |
201 | 콘솔에서 정수를 입력받습니다.
202 |
203 | ```
204 | 엄식? => 콘솔을 입력받아서 1번째 변수에 대입한다.
205 | 어엄식? => 콘솔을 입력받아서 2번째 변수에 대입한다.
206 | ```
207 |
208 | ### 식!
209 |
210 | 콘솔에 정수를 출력합니다.
211 |
212 | ```tsx
213 | 식..! => 콘솔에 2 출력
214 | 식어! => 콘솔에 첫번째 변수 출력
215 | ```
216 |
217 | ### 식ㅋ
218 |
219 | 콘솔에 문자를 출력합니다. `식`과 `ㅋ`사이에 오는 정수를 유니코드 문자로 변환하여 콘솔에 출력합니다. `식`과 `ㅋ`사이에 정수가 주어지지 않으면 개행합니다(`식ㅋ` => `\n`)
220 |
221 | ```tsx
222 | 식........... ........ㅋ => 콘솔에 X 출력
223 | ```
224 |
225 | ## 지시문
226 |
227 | ### 동탄?
228 |
229 | `동탄{정수}?{실행할 명령}`으로 작성합니다. 정수가 0이라면 `실행할 명령`이 실행되며, 그렇지 않다면 다음줄로 넘어갑니다.
230 |
231 | ### 준
232 |
233 | `준` 뒤에 오는 정수번째 줄로 이동합니다. `준.. => 2번째 줄(글자)로 이동`. 원라인코드의 경우에는 `~`로 분리된 코드단위로 카운트하여 이동합니다.
234 |
235 | ### 화이팅!
236 |
237 | `화이팅!`뒤에 오는 정수를 반환하며 프로그램을 종료합니다.
238 |
239 | ## 기타
240 |
241 | - 확장자는 `.umm`입니다.
242 | - One-line 작성은 `\n`을 `~`로 치환합니다. (예제: 구구단 참조)
243 |
244 | # 예제
245 |
246 | [위키를 참조해주세요](https://github.com/rycont/umjunsik-lang/wiki)
247 |
248 | # To-Do
249 | - [ ] gnex-umjunsik [What is Gnex?](https://github.com/rycont/Gnex)
250 | - [x] ~~웹-엄~~
251 | - [x] ~~엄랭파이썬~~
252 |
253 | # History
254 |
255 | - 20200626 0030 : 엄랭 공개
256 | - 20200626 0855 : 엄랭 문서 완성
257 | - 20200625 1256 : 엄랭 Deno 구현체 배포
258 | - 20200804 : 엄랭v2
259 | 1. 모든 콘솔 출력은 인라인
260 | 1. `화이팅!` 후에 오는 문자열을 반환하며 프로그램이 종료
261 | 1. 새 문법 추가: `식ㅋ`
262 | 1. 새 문법 추가: `동탄?`
263 | 1. `화이팅!`의 명세 변경
264 | - 20200805 : 문서 개정
265 | 1. `동탄?` 설명 추가
266 | 1. `화이팅!` 설명 변경
267 | 1. 지시문들을 별도의 단락으로 분리
268 | - 20200912 : 99병의 맥주 예제
269 | - 20200915 : 엄랭v2-엄랭노드 구현체 배포
270 | - 20201017 : 엄랭v2-파이썬 구현체 배포 by [Steve28](https://github.com/pl-Steve28-lq)
271 | - 20201105 : 웹-엄: 자바스크립트로 된 엄랭 처리기(웹런타임) 배포 by [PMH](https://github.com/pmh-only)
272 | - 20210530 : 엄씨(엄랭-C 컴파일러) 배포 by [Rok](https://github.com/Rokr0k)
273 | - 20210809 : 엄랭 C# 구현체 배포 by [noname0310](https://github.com/noname0310)
274 | - 20220201 : 엄랭 코틀린 구현체 배포 by [shs3182ym](https://github.com/shs3182ym)
275 | - 20220203 : 엄랭 Go 구현체 배포 by [alvin1007](https://github.com/alvin1007)
276 | - 20220203 : 엄랭 러스트 구현체 배포 by [kiwiyou](https://github.com/kiwiyou)
277 | - 20220207 : 엄랭v3 초안 작성중
278 | 1. N번째 변수 접근 / 대입 표현
279 | 1. 변수간 덧셈연산
280 |
--------------------------------------------------------------------------------
/examples/addition_calculator.umm:
--------------------------------------------------------------------------------
1 | 어떻게
2 |
3 | 엄식?
4 | 어엄식?
5 |
6 | 동탄어?준... ....
7 |
8 | 엄어,
9 | 어엄어어.
10 |
11 | 준.. ...
12 | 식어어!
13 |
14 | 이 사람이름이냐ㅋㅋ
15 |
--------------------------------------------------------------------------------
/examples/evenodd.umm:
--------------------------------------------------------------------------------
1 | 어떻게
2 | 엄식?
3 | 어엄
4 | 어어엄..... ..... ....
5 |
6 | 엄어,
7 | 동탄어?준.... ....
8 | 어엄어어.
9 | 엄어,
10 | 동탄어?준.... ....
11 | 어엄어어,
12 | 준.. ...
13 |
14 |
15 |
16 | 동탄어어?준.... ......
17 | 식어어어.ㅋ
18 | 식어어어..................ㅋ
19 | 식어어어.ㅋ
20 | 식어어어..........ㅋ
21 | 준..... ......
22 |
23 |
24 | 식어어어...........ㅋ
25 | 식어어어ㅋ
26 | 식어어어ㅋ
27 |
28 |
29 |
30 | 화이팅,.!
31 | 이 사람이름이냐ㅋㅋ
--------------------------------------------------------------------------------
/examples/factorial_calculator.umm:
--------------------------------------------------------------------------------
1 | 어떻게
2 |
3 | 엄.
4 | 어엄식?
5 |
6 | 동탄어어?준.................
7 |
8 | 엄어 어어
9 | 어엄어어,
10 |
11 | 동탄어어?준....... ..
12 | 준......
13 |
14 | 식어!
15 | 준...... ...
16 |
17 | 식.!
18 |
19 | 화이팅.,!
20 | 이 사람이름이냐ㅋㅋ
--------------------------------------------------------------------------------
/examples/gugudan.umm:
--------------------------------------------------------------------------------
1 | 어떻게
2 |
3 | 엄..
4 | 어엄.
5 | 어어엄........
6 | 어어어엄.........
7 |
8 | 식어!
9 | 식........ ....ㅋ
10 | 식........... ........ㅋ
11 | 식........ ....ㅋ
12 | 식어어!
13 | 식........ ....ㅋ
14 | 식.............................................................ㅋ
15 | 식........ ....ㅋ
16 | 식어 어어!
17 | 식ㅋ
18 | 어어어엄어어어어,
19 | 어엄어어.
20 | 동탄어어어어?준.......................
21 | 준........
22 |
23 | 엄어.
24 | 어어엄어어어,
25 | 어어어엄.........
26 | 어엄.
27 | 동탄어어어?화이팅!.
28 | 식ㅋ
29 | 준........
30 |
31 | 이 사람이름이냐ㅋㅋ
32 |
--------------------------------------------------------------------------------
/examples/helloworld.umm:
--------------------------------------------------------------------------------
1 | 어떻게
2 |
3 | 엄
4 | 어엄
5 | 어어엄
6 | 어어어엄
7 | 어어어어엄
8 | 어어어어어엄
9 | 어어어어어어엄
10 | 어어어어어어어엄
11 |
12 | 엄어..........
13 | 동탄어?준..... .....
14 |
15 | 어엄어어.......
16 |
17 | 어어엄어어어..........
18 |
19 | 어어어엄어어어어...
20 |
21 | 어어어어엄어어어어어.
22 |
23 | 엄어,
24 | 준.............
25 |
26 | 어엄어어..
27 | 식어어ㅋ
28 |
29 | 어어엄어어어.
30 | 식어어어ㅋ
31 | 어어엄어어어.......
32 | 식어어어ㅋ
33 | 식어어어ㅋ
34 | 어어엄어어어...
35 | 식어어어ㅋ
36 |
37 | 어어어엄어어어어..............
38 | 식어어어어ㅋ
39 | 어어어엄어어어어,,,,,,,,,,,,
40 | 식어어어어ㅋ
41 |
42 | 어엄어어...............
43 | 식어어ㅋ
44 |
45 | 식어어어ㅋ
46 | 어어엄어어어...
47 | 식어어어ㅋ
48 | 어어엄어어어,,,,,,
49 | 식어어어ㅋ
50 | 어어엄어어어,,,,,,,,
51 | 식어어어ㅋ
52 |
53 | 어어어엄어어어어.
54 | 식어어어어ㅋ
55 |
56 | 화이팅!.,
57 |
58 | 이 사람이름이냐ㅋㅋ
59 |
--------------------------------------------------------------------------------
/examples/pyramid.umm:
--------------------------------------------------------------------------------
1 | 어떻게
2 |
3 | 엄
4 | 어엄
5 | 어어엄
6 | 어어어엄
7 | 어어어어엄
8 | 어어어어어엄
9 | 어어어어어어엄
10 |
11 | 엄식?
12 |
13 | 어어엄어어어.....................
14 | 동탄어어어?준.. ...........
15 | 어어엄어어어,
16 |
17 | 어어어엄어어어어.
18 |
19 | 어어어어엄어어어어어.
20 |
21 | 준.. .......
22 |
23 | 동탄어어어어?준.............................
24 | 어어어엄어어어어,
25 |
26 | 어어어어엄어어어어어.
27 |
28 | 준.......................
29 |
30 | 어어어어어엄어어어어어어..........
31 |
32 | 동탄어?준.. ...............................
33 | 엄어,
34 |
35 | 어엄어어.
36 | 동탄어어?준.. .. ...........
37 | 어엄어어,
38 |
39 | 어어엄어어어.
40 |
41 | 어어어엄어어어어.
42 |
43 | 준.. .. ... ...
44 |
45 | 동탄어어어어?준... .................
46 | 어어어엄어어어어,
47 |
48 | 어엄어어.
49 |
50 | 준... ... .....
51 |
52 | 동탄어어어?준.. .............................
53 | 어어엄어어어,
54 |
55 | 식어어어어어ㅋ
56 |
57 | 준.. .. .............
58 |
59 | 식ㅋ
60 |
61 | 준.. .. .. .. ..
62 |
63 | 화이팅!.,
64 |
65 | 이 사람이름이냐ㅋㅋ
66 |
--------------------------------------------------------------------------------
/examples/sqrt.umm:
--------------------------------------------------------------------------------
1 | 어떻게
2 | 엄식?
3 | 어어어어어어어어어어어어어엄식?
4 | 어엄..... .. ..... ..
5 | 어어어엄어어
6 | 어어엄어
7 | 동탄어어어어?화이팅!,
8 | 동탄어어어?준.............
9 | 어어엄어어어,
10 | 어어어엄어어어어,
11 | 준.......
12 |
13 | 어어엄어
14 | 어어어엄.
15 | 어어어어어엄.,
16 |
17 | 어어어어엄어어어어
18 | 동탄어어어?준.. .. .......
19 | 동탄어어어어어?준... .. .. ..
20 | 어어엄어어어,
21 | 어어어어엄어어어어어,
22 | 준.. ... ...
23 |
24 | 어어어엄어어어어..
25 | 어어어어어엄어어어어어어.
26 | 준.... ....
27 |
28 | 동탄어어어어어어어어어어어어어어?준... ...........
29 | 동탄어어어어어?준... ...........
30 | 식어어어어어어!
31 | 식.. .......................ㅋ
32 | 준.. .. ... ...
33 | 준.. .. .. .. .. .. ..
34 |
35 |
36 | 어어어어어어엄어어어어어어
37 | 동탄어어어어어?준.. ... .......
38 | 어어어어엄어어어어어,
39 | 어어어엄어어어어,
40 | 준.....................................
41 |
42 |
43 | 동탄어어어어어어어?준.. .. .. .. ...
44 | 어어어어어어엄어어어어어어어,
45 | 어어어어어엄어어어어어어.
46 | 준.. ... .......
47 |
48 | 어엄... ...
49 | 어어엄어어어어어어
50 | 어어어어어어엄어어어어어어
51 | 동탄어어?준.. .. ... .....
52 | 동탄어어어?준... ...................
53 | 어어어어어엄어어어어어어.
54 | 어어엄어어어,
55 | 준.. .. .............
56 |
57 | 어엄어어,
58 | 어어엄어어어어어어어
59 | 준... .................
60 | 어엄... ... ...........
61 | 어어어어어어어어어어엄어어어어
62 | 어어엄어어어어
63 | 동탄어어?준.. .. .. ... ...
64 | 동탄어어어?준.. .. .................
65 | 어어어어어어어어어어엄어어어어어어어어어어어.
66 | 어어엄어어어,
67 | 준.. .. .. .. .. ..
68 | 어엄어어,
69 | 준.. ...............................
70 |
71 |
72 | 어엄.,
73 | 어어엄어어어어어어
74 | 어어어엄어어
75 | 동탄어어어어?준.. .. .. .. .....
76 | 어어엄어어어.
77 | 어어어엄어어어어,
78 | 준... ..... .....
79 |
80 | 어어어어어어어엄어어어
81 | 어어어어엄어어어
82 | 동탄어어?준.. .. ...............................
83 | 어어어어어어어어엄어어,
84 | 동탄어어어어어어어어어?준.. ...............................................
85 | 동탄어어어어어어어어?준... ... .. .....
86 | 어어어어어어어엄어어어어어어어어,
87 | 어어어어엄어어어어어.
88 | 준..... .................
89 |
90 | 어어어어어어어어엄어어어어어어어어어,
91 | 어어어어어어어엄어어어
92 | 준.. .. ... .......
93 |
94 | 어어어어어어어어어어어엄어어어어어어어어어어어
95 | 동탄어어어어어어어어어어어어?준.. .. ..... .....
96 | 동탄어어어어어?준.. ... ...................
97 | 어어어어어어어어어어어엄어어어어어어어어어어어어,
98 | 어어어어엄어어어어어,
99 | 준..... ...................
100 | 동탄어어어어어?준... ... .............
101 | 어엄어어,
102 | 식어어!
103 | 어어어엄어어어어어어어어어어어어어
104 | 어어엄어어어,
105 | 동탄어어?준.. ..... ...........
106 | 어엄어어,
107 | 어어엄어어어.
108 | 준..... ... .......
109 |
110 | 어어어어어어어어어어어어어엄어어어어어어어어어어어어어어,
111 | 동탄어어어어어어어어어어어어어어?화이팅!.,
112 | 어어어어어엄어어어
113 | 준... .. .. .. ..
114 |
115 |
116 | 어어어어어어어어어어어어엄어어어어어어어어어어어어
117 | 어엄어어.
118 | 준.........................................................................
119 |
120 | 식어어!
121 | 화이팅!.,
122 |
123 |
124 | 어어어어엄.,
125 | 준.. ...............................................
126 |
127 |
128 | 동탄어어어어어?어어어어어엄어어어어어어.
129 | 식어어어어어어!
130 | 화이팅!.,
131 | 이 사람이름이냐ㅋㅋ
--------------------------------------------------------------------------------
/examples/string_test.umm:
--------------------------------------------------------------------------------
1 | 어떻게
2 | 엄..
3 | 엄어 ..
4 | 엄어 ..
5 | 엄어 ...........
6 | 식어ㅋ
7 | 이 사람이름이냐ㅋㅋ
8 |
--------------------------------------------------------------------------------
/examples/tree.umm:
--------------------------------------------------------------------------------
1 | 어떻게
2 |
3 | 엄
4 | 어엄
5 | 어어엄
6 | 어어어엄
7 | 어어어어엄
8 | 어어어어어엄
9 | 어어어어어어엄
10 | 어어어어어어어엄
11 | 어어어어어어어어엄
12 | 어어어어어어어어어엄
13 |
14 | 엄어....
15 | 동탄어?준... .......
16 |
17 | 어엄어어........
18 |
19 | 엄어,
20 | 준... .....
21 |
22 | 동탄어어?준.. ... .....
23 | 어엄어어,
24 |
25 | 엄어.
26 |
27 | 어어엄어어어.
28 |
29 | 준.. ...........
30 |
31 | 동탄어어어?준.....................................
32 | 어어엄어어어,
33 |
34 | 어엄어어.
35 |
36 | 준...............................
37 |
38 | 어엄어어...
39 |
40 | 동탄어어어?준.. .......................
41 | 어어엄어어어,
42 |
43 | 어엄어어.
44 |
45 | 준.. .. .. .....
46 |
47 | 어어어엄어어어어......
48 | 동탄어어어어?준.. ... ... ...
49 |
50 | 어어엄어어어.......
51 |
52 | 어어어엄어어어어,
53 | 준.. .. .. .. ...
54 | 어어어엄어어어어..........
55 |
56 | 어어어어엄어어어어어.....
57 | 동탄어어어어어?준... ... .......
58 | 어어어어엄어어어어어,
59 |
60 | 식어ㅋ
61 |
62 | 준... ...................
63 |
64 | 식어어어ㅋ
65 |
66 | 식ㅋ
67 |
68 | 어어어어엄어어어어어.....
69 | 동탄어어어어어?준....... ...........
70 | 어어어어엄어어어어어,
71 |
72 | 어어어어어엄어어어어어어.
73 |
74 | 어어어어어어엄어어어어어어어.
75 |
76 | 준... .......................
77 |
78 | 동탄어어어어어어어?준.. .. ... .......
79 | 어어어어어어엄어어어어어어어,
80 |
81 | 어어어어엄어어어어어.
82 |
83 | 준.. ... .............
84 | 어어어어어어엄어어어어어어어.
85 |
86 |
87 | 동탄어어어어어?준.. ...............................................................................
88 |
89 | 동탄어어어어어어?준.................................................................................................
90 | 어어어어어엄어어어어어어,
91 |
92 | 어어어어어어어엄어어어어어어어어.
93 |
94 | 어어어어어어어어엄어어어어어어어어어.
95 |
96 | 준.........................................................................................
97 |
98 | 동탄어어어어어어어어어?준.. .. .. .............
99 | 어어어어어어어어엄어어어어어어어어어,
100 |
101 | 어어어어어엄어어어어어어.
102 |
103 | 준.. ....... .......
104 |
105 | 동탄어어어어어어?준... .....................................
106 | 어어어어어엄어어어어어어,
107 |
108 | 식어ㅋ
109 |
110 | 준... ..... .......
111 |
112 | 동탄어어어어어어어어?준.. ...........................................................
113 | 어어어어어어어엄어어어어어어어어,
114 |
115 | 어어어어어엄어어어어어어.
116 |
117 | 준.. .. .. .. .......
118 |
119 | 동탄어어어어어어어?준...............................................................................................................................
120 |
121 | 어어어어어어어엄어어어어어어어어.
122 |
123 | 어어어어어어어어엄어어어어어어어어어.
124 |
125 | 어어어어어어엄어어어어어어어,
126 | 준....... .................
127 |
128 | 동탄어어어어어어어어어?준.. ...................................................................
129 | 어어어어어어어어엄어어어어어어어어어,
130 |
131 | 어어어어어어엄어어어어어어어.
132 |
133 | 준.. .. .. .. .. .. ..
134 |
135 | 동탄어어어어어어어?준... ...............................................
136 | 어어어어어어엄어어어어어어어,
137 |
138 | 식어어ㅋ
139 |
140 | 준... ... ... .....
141 |
142 | 동탄어어어어어어어어?준.. .. .....................................
143 | 어어어어어어어엄어어어어어어어어,
144 |
145 | 어어어어어어엄어어어어어어어.
146 |
147 | 준.. .......................................................................
148 |
149 | 어어어어어어엄어어어어어어어..
150 |
151 | 어어어어어엄어어어어어어,
152 |
153 | 어어어어엄어어어어어,
154 |
155 | 식ㅋ
156 |
157 | 준... .............................
158 | 어어어어엄어어어어어........
159 | 동탄어어어어어?준... ..... ...........
160 | 어어어어엄어어어어어,
161 |
162 | 어어어어어엄어어어어어어.........
163 |
164 | 준... .....................................................
165 | 어어어어엄어어어어어...
166 |
167 | 어어어어어엄어어어어어어.
168 |
169 | 동탄어어어어어?준.. .. .. .......................
170 | 어어어어엄어어어어어,
171 |
172 | 식어ㅋ
173 | 식어ㅋ
174 | 식어ㅋ
175 | 식어ㅋ
176 |
177 | 식어어어어어어ㅋ
178 | 식어어어어어어ㅋ
179 | 식어어어어어어ㅋ
180 |
181 | 식ㅋ
182 |
183 | 준............. .............
184 |
185 | 화이팅!.,
186 |
187 | 이 사람이름이냐ㅋㅋ
188 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import setup, find_packages
2 |
3 | setup(
4 | name="umjunsik",
5 | version="2.0.2",
6 | packages=find_packages(),
7 | entry_points={
8 | "console_scripts": [
9 | "umjunsik=umjunsik-lang-python.__main__:main",
10 | ],
11 | },
12 | author="rycont",
13 | author_email="rycont@outlook.kr",
14 | description="어떻게 엄준식이 언어이름이냐🤣",
15 | long_description=open("../README.md", "r", encoding="UTF-8").read(),
16 | long_description_content_type="text/markdown",
17 | url="https://github.com/rycont/umjunsik-lang",
18 | classifiers=[
19 | "Intended Audience :: Developers",
20 | "License :: OSI Approved :: MIT License",
21 | "Programming Language :: Python :: 3",
22 | "Programming Language :: Python :: 3.7",
23 | "Programming Language :: Python :: 3.8",
24 | "Programming Language :: Python :: 3.9",
25 | "Programming Language :: Python :: 3.10",
26 | ],
27 | )
--------------------------------------------------------------------------------
/umjunsik-lang-cc/.gitignore:
--------------------------------------------------------------------------------
1 | *.o
2 | *.s
3 | *.S
4 | bin/
--------------------------------------------------------------------------------
/umjunsik-lang-cc/Makefile:
--------------------------------------------------------------------------------
1 | C_SOURCES = $(wildcard src/*.c)
2 | HEADERS = $(wildcard src/*.h)
3 | OBJ = $(C_SOURCES:src/%.c=bin/%.o)
4 |
5 | CC = gcc
6 | CFLAGS = -Wall
7 |
8 | TARGET = bin/umcc
9 |
10 | ${TARGET}: ${OBJ}
11 | ${CC} ${CFLAGS} $^ -o $@
12 |
13 | bin/%.o: src/%.c ${HEADERS} bin
14 | ${CC} ${CFLAGS} -c $< -o $@
15 |
16 | bin:
17 | mkdir bin
18 |
19 | clean:
20 | rm -rf ${OBJ} ${TARGET} bin
--------------------------------------------------------------------------------
/umjunsik-lang-cc/src/file.c:
--------------------------------------------------------------------------------
1 | #include "file.h"
2 | #include
3 |
4 | void moveFile(char *_Old, char *_New) {
5 | FILE *old = fopen(_Old, "r");
6 | FILE *new = fopen(_New, "w");
7 |
8 | char c;
9 | while((c = fgetc(old)) != EOF) {
10 | fputc(c, new);
11 | }
12 |
13 | fclose(old);
14 | fclose(new);
15 |
16 | remove(_Old);
17 | }
--------------------------------------------------------------------------------
/umjunsik-lang-cc/src/file.h:
--------------------------------------------------------------------------------
1 | #ifndef FILE_H
2 | #define FILE_H
3 |
4 | void moveFile(char *_Old, char *_New);
5 |
6 | #endif
--------------------------------------------------------------------------------
/umjunsik-lang-cc/src/info.h:
--------------------------------------------------------------------------------
1 | #ifndef INFO_H
2 | #define INFO_H
3 |
4 | #define HELP_S \
5 | "Usage: umcc [options] file...\n" \
6 | "Options:\n" \
7 | " -h | --help Display this helpful text :)\n" \
8 | " -v | --version Display compiler information.\n" \
9 | " -o Place the output into .\n" \
10 | " -c Compile to C source file.\n" \
11 | " -s Compile to assembly source file.\n" \
12 | "\n" \
13 | "For bug report, please contact\n" \
14 | ".\n"
15 | #define VERSION_S \
16 | "umcc 1.1\n" \
17 | "Copyright (C) 2022 Rok\n" \
18 | "\n" \
19 | "umjunsik-lang\n" \
20 | "Copyright (C) 2022 Rycont\n"
21 |
22 | #define SRC 0x1
23 | #define ASM 0x2
24 |
25 | #endif
26 |
--------------------------------------------------------------------------------
/umjunsik-lang-cc/src/main.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #ifdef __unix__
5 | #include
6 | #endif
7 | #include "info.h"
8 | #include "parse.h"
9 | #include "string.h"
10 | #include "file.h"
11 |
12 | int main(int argc, char *argv[])
13 | {
14 | FILE *input = NULL;
15 | FILE *output = NULL;
16 | int mode = 0;
17 | char input_path[4096] = {0};
18 | char output_path[4096] = {0};
19 | char command[8500] = {0};
20 | int i;
21 | for (i = 1; i < argc; i++)
22 | {
23 | if (argv[i][0] == '-')
24 | {
25 | if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
26 | {
27 | fprintf(stdout, HELP_S);
28 | exit(0);
29 | }
30 | else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0)
31 | {
32 | fprintf(stdout, VERSION_S);
33 | exit(0);
34 | }
35 | else if (strcmp(argv[i], "-o") == 0 && i + 1 < argc)
36 | {
37 | strcpy(output_path, argv[++i]);
38 | }
39 | else if (strcmp(argv[i], "-c") == 0)
40 | {
41 | mode = SRC;
42 | }
43 | else if (strcmp(argv[i], "-s") == 0)
44 | {
45 | mode = ASM;
46 | }
47 | else
48 | {
49 | fprintf(stderr, "어떻게 이게 옵션이냐ㅋㅋ\n");
50 | exit(1);
51 | }
52 | }
53 | else
54 | {
55 | strcpy(input_path, argv[i]);
56 | }
57 | }
58 | if (input_path[0] == 0)
59 | {
60 | fprintf(stderr, "어떻게 파일 이름이 없냐ㅋㅋ\n");
61 | exit(1);
62 | }
63 | if (strcmp(strrchr(input_path, '.'), ".umm"))
64 | {
65 | fprintf(stderr, "어떻게 %s가 umm파일이냐ㅋㅋ\n", strrchr(input_path, '.'));
66 | exit(1);
67 | }
68 | input = fopen(input_path, "r");
69 | if (input == NULL)
70 | {
71 | fprintf(stderr, "어떻게 %s가 파일 이름이냐ㅋㅋ\n", input_path);
72 | exit(1);
73 | }
74 | #ifdef __unix__
75 | fseek(input, 0L, SEEK_END);
76 | long l = ftell(input);
77 | rewind(input);
78 | char *text = malloc(sizeof(char) * l + 1);
79 | memset(text, 0, sizeof(char) * l + 1);
80 | fread(text, sizeof(char), l, input);
81 | fclose(input);
82 | int ispipe = 1;
83 |
84 | switch (mode)
85 | {
86 | case SRC:
87 | if (output_path[0] == 0)
88 | {
89 | strcpy(output_path, strrchr(input_path, '/') + 1);
90 | strcpy(strrchr(output_path, '.'), ".c");
91 | }
92 | output = fopen(output_path, "w");
93 | ispipe = 0;
94 | break;
95 | case ASM:
96 | if (output_path[0] == 0)
97 | {
98 | strcpy(output_path, strrchr(input_path, '/') + 1);
99 | strcpy(strrchr(output_path, '.'), ".s");
100 | }
101 | sprintf(command, "gcc -S -x c - -o \"%s\"", output_path);
102 | output = popen(command, "w");
103 | break;
104 | default:
105 | if (output_path[0] == 0)
106 | {
107 | strcpy(output_path, "a.out");
108 | }
109 | sprintf(command, "gcc -x c - -o \"%s\"", output_path);
110 | output = popen(command, "w");
111 | break;
112 | }
113 | if (parse(text, output))
114 | {
115 | fprintf(stderr, "어떻게 이 코드가 엄랭이냐ㅋㅋ\n");
116 | free(text);
117 | ispipe ? pclose(output) : fclose(output);
118 | remove(output_path);
119 | exit(1);
120 | }
121 | free(text);
122 | ispipe ? pclose(output) : fclose(output);
123 | #else
124 | char temp_path[4096] = {0};
125 | strcpy(temp_path, strrchr(input_path, '/') + 1);
126 | strcpy(strrchr(temp_path, '.'), ".c");
127 | fseek(input, 0L, SEEK_END);
128 | long l = ftell(input);
129 | rewind(input);
130 | char *text = malloc(sizeof(char) * l + 1);
131 | memset(text, 0, sizeof(char) * l + 1);
132 | fread(text, sizeof(char), l, input);
133 | fclose(input);
134 | output = fopen(temp_path, "w");
135 | if (parse(text, output))
136 | {
137 | fprintf(stderr, "어떻게 이 코드가 엄랭이냐ㅋㅋ\n");
138 | free(text);
139 | fclose(output);
140 | remove(temp_path);
141 | exit(1);
142 | }
143 | free(text);
144 | fclose(output);
145 | switch (mode)
146 | {
147 | case SRC:
148 | if (output_path[0])
149 | {
150 | moveFile(temp_path, output_path);
151 | remove(temp_path);
152 | }
153 | break;
154 | case ASM:
155 | if (output_path[0] == 0)
156 | {
157 | strcpy(output_path, strrchr(input_path, '/') + 1);
158 | strcpy(strrchr(output_path, '.'), ".s");
159 | }
160 | sprintf(command, "gcc -S \"%s\" -o \"%s\"", temp_path, output_path);
161 | system(command);
162 | remove(temp_path);
163 | break;
164 | default:
165 | if (output_path[0] == 0)
166 | {
167 | sprintf(command, "gcc \"%s\"", temp_path);
168 | }
169 | else
170 | {
171 | sprintf(command, "gcc \"%s\" -o \"%s\"", temp_path, output_path);
172 | }
173 | system(command);
174 | remove(temp_path);
175 | break;
176 | }
177 | #endif
178 | return 0;
179 | }
--------------------------------------------------------------------------------
/umjunsik-lang-cc/src/parse.c:
--------------------------------------------------------------------------------
1 | #include "parse.h"
2 | #include
3 | #include
4 | #include "string.h"
5 |
6 | char **splitLines(char *text) {
7 | size_t nc=1, i, j, k;
8 | for(i=0; text[i]; i++) {
9 | if(text[i] == '\n' || text[i] == '~') {
10 | nc++;
11 | }
12 | }
13 | char **lines = malloc(sizeof(char *)*(nc+1));
14 | for(i=0, j=0; i\n"
129 | "#include\n"
130 | "#define JUN(n) switch(n){");
131 | for(i=1; i
5 |
6 | int parse(char *text, FILE *output);
7 |
8 | #endif
--------------------------------------------------------------------------------
/umjunsik-lang-cc/src/string.c:
--------------------------------------------------------------------------------
1 | #include "string.h"
2 |
3 | size_t stridx(const char *_Str, const char *_Target) {
4 | size_t l = strlen(_Target);
5 | size_t i, j;
6 | int flag;
7 | for(i=0; _Str[i]; i++) {
8 | flag = 1;
9 | for(j=0; j
5 |
6 | size_t stridx(const char *_Str1, const char *_Str2);
7 | int strstt(const char *_Str1, const char *_Str2);
8 | void strsub(char *_Des, const char *_Str, size_t _Idx, size_t _Len);
9 |
10 | #endif
--------------------------------------------------------------------------------
/umjunsik-lang-csharp/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.toptal.com/developers/gitignore/api/csharp
3 | # Edit at https://www.toptal.com/developers/gitignore?templates=csharp
4 |
5 | ### Csharp ###
6 | ## Ignore Visual Studio temporary files, build results, and
7 | ## files generated by popular Visual Studio add-ons.
8 | ##
9 | ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
10 |
11 | # User-specific files
12 | *.rsuser
13 | *.suo
14 | *.user
15 | *.userosscache
16 | *.sln.docstates
17 |
18 | # User-specific files (MonoDevelop/Xamarin Studio)
19 | *.userprefs
20 |
21 | # Mono auto generated files
22 | mono_crash.*
23 |
24 | # Build results
25 | [Dd]ebug/
26 | [Dd]ebugPublic/
27 | [Rr]elease/
28 | [Rr]eleases/
29 | x64/
30 | x86/
31 | [Ww][Ii][Nn]32/
32 | [Aa][Rr][Mm]/
33 | [Aa][Rr][Mm]64/
34 | bld/
35 | [Bb]in/
36 | [Oo]bj/
37 | [Ll]og/
38 | [Ll]ogs/
39 |
40 | # Visual Studio 2015/2017 cache/options directory
41 | .vs/
42 | # Uncomment if you have tasks that create the project's static files in wwwroot
43 | #wwwroot/
44 |
45 | # Visual Studio 2017 auto generated files
46 | Generated\ Files/
47 |
48 | # MSTest test Results
49 | [Tt]est[Rr]esult*/
50 | [Bb]uild[Ll]og.*
51 |
52 | # NUnit
53 | *.VisualState.xml
54 | TestResult.xml
55 | nunit-*.xml
56 |
57 | # Build Results of an ATL Project
58 | [Dd]ebugPS/
59 | [Rr]eleasePS/
60 | dlldata.c
61 |
62 | # Benchmark Results
63 | BenchmarkDotNet.Artifacts/
64 |
65 | # .NET Core
66 | project.lock.json
67 | project.fragment.lock.json
68 | artifacts/
69 |
70 | # ASP.NET Scaffolding
71 | ScaffoldingReadMe.txt
72 |
73 | # StyleCop
74 | StyleCopReport.xml
75 |
76 | # Files built by Visual Studio
77 | *_i.c
78 | *_p.c
79 | *_h.h
80 | *.ilk
81 | *.meta
82 | *.obj
83 | *.iobj
84 | *.pch
85 | *.pdb
86 | *.ipdb
87 | *.pgc
88 | *.pgd
89 | *.rsp
90 | *.sbr
91 | *.tlb
92 | *.tli
93 | *.tlh
94 | *.tmp
95 | *.tmp_proj
96 | *_wpftmp.csproj
97 | *.log
98 | *.tlog
99 | *.vspscc
100 | *.vssscc
101 | .builds
102 | *.pidb
103 | *.svclog
104 | *.scc
105 |
106 | # Chutzpah Test files
107 | _Chutzpah*
108 |
109 | # Visual C++ cache files
110 | ipch/
111 | *.aps
112 | *.ncb
113 | *.opendb
114 | *.opensdf
115 | *.sdf
116 | *.cachefile
117 | *.VC.db
118 | *.VC.VC.opendb
119 |
120 | # Visual Studio profiler
121 | *.psess
122 | *.vsp
123 | *.vspx
124 | *.sap
125 |
126 | # Visual Studio Trace Files
127 | *.e2e
128 |
129 | # TFS 2012 Local Workspace
130 | $tf/
131 |
132 | # Guidance Automation Toolkit
133 | *.gpState
134 |
135 | # ReSharper is a .NET coding add-in
136 | _ReSharper*/
137 | *.[Rr]e[Ss]harper
138 | *.DotSettings.user
139 |
140 | # TeamCity is a build add-in
141 | _TeamCity*
142 |
143 | # DotCover is a Code Coverage Tool
144 | *.dotCover
145 |
146 | # AxoCover is a Code Coverage Tool
147 | .axoCover/*
148 | !.axoCover/settings.json
149 |
150 | # Coverlet is a free, cross platform Code Coverage Tool
151 | coverage*.json
152 | coverage*.xml
153 | coverage*.info
154 |
155 | # Visual Studio code coverage results
156 | *.coverage
157 | *.coveragexml
158 |
159 | # NCrunch
160 | _NCrunch_*
161 | .*crunch*.local.xml
162 | nCrunchTemp_*
163 |
164 | # MightyMoose
165 | *.mm.*
166 | AutoTest.Net/
167 |
168 | # Web workbench (sass)
169 | .sass-cache/
170 |
171 | # Installshield output folder
172 | [Ee]xpress/
173 |
174 | # DocProject is a documentation generator add-in
175 | DocProject/buildhelp/
176 | DocProject/Help/*.HxT
177 | DocProject/Help/*.HxC
178 | DocProject/Help/*.hhc
179 | DocProject/Help/*.hhk
180 | DocProject/Help/*.hhp
181 | DocProject/Help/Html2
182 | DocProject/Help/html
183 |
184 | # Click-Once directory
185 | publish/
186 |
187 | # Publish Web Output
188 | *.[Pp]ublish.xml
189 | *.azurePubxml
190 | # Note: Comment the next line if you want to checkin your web deploy settings,
191 | # but database connection strings (with potential passwords) will be unencrypted
192 | *.pubxml
193 | *.publishproj
194 |
195 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
196 | # checkin your Azure Web App publish settings, but sensitive information contained
197 | # in these scripts will be unencrypted
198 | PublishScripts/
199 |
200 | # NuGet Packages
201 | *.nupkg
202 | # NuGet Symbol Packages
203 | *.snupkg
204 | # The packages folder can be ignored because of Package Restore
205 | **/[Pp]ackages/*
206 | # except build/, which is used as an MSBuild target.
207 | !**/[Pp]ackages/build/
208 | # Uncomment if necessary however generally it will be regenerated when needed
209 | #!**/[Pp]ackages/repositories.config
210 | # NuGet v3's project.json files produces more ignorable files
211 | *.nuget.props
212 | *.nuget.targets
213 |
214 | # Microsoft Azure Build Output
215 | csx/
216 | *.build.csdef
217 |
218 | # Microsoft Azure Emulator
219 | ecf/
220 | rcf/
221 |
222 | # Windows Store app package directories and files
223 | AppPackages/
224 | BundleArtifacts/
225 | Package.StoreAssociation.xml
226 | _pkginfo.txt
227 | *.appx
228 | *.appxbundle
229 | *.appxupload
230 |
231 | # Visual Studio cache files
232 | # files ending in .cache can be ignored
233 | *.[Cc]ache
234 | # but keep track of directories ending in .cache
235 | !?*.[Cc]ache/
236 |
237 | # Others
238 | ClientBin/
239 | ~$*
240 | *~
241 | *.dbmdl
242 | *.dbproj.schemaview
243 | *.jfm
244 | *.pfx
245 | *.publishsettings
246 | orleans.codegen.cs
247 |
248 | # Including strong name files can present a security risk
249 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
250 | #*.snk
251 |
252 | # Since there are multiple workflows, uncomment next line to ignore bower_components
253 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
254 | #bower_components/
255 |
256 | # RIA/Silverlight projects
257 | Generated_Code/
258 |
259 | # Backup & report files from converting an old project file
260 | # to a newer Visual Studio version. Backup files are not needed,
261 | # because we have git ;-)
262 | _UpgradeReport_Files/
263 | Backup*/
264 | UpgradeLog*.XML
265 | UpgradeLog*.htm
266 | ServiceFabricBackup/
267 | *.rptproj.bak
268 |
269 | # SQL Server files
270 | *.mdf
271 | *.ldf
272 | *.ndf
273 |
274 | # Business Intelligence projects
275 | *.rdl.data
276 | *.bim.layout
277 | *.bim_*.settings
278 | *.rptproj.rsuser
279 | *- [Bb]ackup.rdl
280 | *- [Bb]ackup ([0-9]).rdl
281 | *- [Bb]ackup ([0-9][0-9]).rdl
282 |
283 | # Microsoft Fakes
284 | FakesAssemblies/
285 |
286 | # GhostDoc plugin setting file
287 | *.GhostDoc.xml
288 |
289 | # Node.js Tools for Visual Studio
290 | .ntvs_analysis.dat
291 | node_modules/
292 |
293 | # Visual Studio 6 build log
294 | *.plg
295 |
296 | # Visual Studio 6 workspace options file
297 | *.opt
298 |
299 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
300 | *.vbw
301 |
302 | # Visual Studio 6 auto-generated project file (contains which files were open etc.)
303 | *.vbp
304 |
305 | # Visual Studio 6 workspace and project file (working project files containing files to include in project)
306 | *.dsw
307 | *.dsp
308 |
309 | # Visual Studio 6 technical files
310 |
311 | # Visual Studio LightSwitch build output
312 | **/*.HTMLClient/GeneratedArtifacts
313 | **/*.DesktopClient/GeneratedArtifacts
314 | **/*.DesktopClient/ModelManifest.xml
315 | **/*.Server/GeneratedArtifacts
316 | **/*.Server/ModelManifest.xml
317 | _Pvt_Extensions
318 |
319 | # Paket dependency manager
320 | .paket/paket.exe
321 | paket-files/
322 |
323 | # FAKE - F# Make
324 | .fake/
325 |
326 | # CodeRush personal settings
327 | .cr/personal
328 |
329 | # Python Tools for Visual Studio (PTVS)
330 | __pycache__/
331 | *.pyc
332 |
333 | # Cake - Uncomment if you are using it
334 | # tools/**
335 | # !tools/packages.config
336 |
337 | # Tabs Studio
338 | *.tss
339 |
340 | # Telerik's JustMock configuration file
341 | *.jmconfig
342 |
343 | # BizTalk build output
344 | *.btp.cs
345 | *.btm.cs
346 | *.odx.cs
347 | *.xsd.cs
348 |
349 | # OpenCover UI analysis results
350 | OpenCover/
351 |
352 | # Azure Stream Analytics local run output
353 | ASALocalRun/
354 |
355 | # MSBuild Binary and Structured Log
356 | *.binlog
357 |
358 | # NVidia Nsight GPU debugger configuration file
359 | *.nvuser
360 |
361 | # MFractors (Xamarin productivity tool) working folder
362 | .mfractor/
363 |
364 | # Local History for Visual Studio
365 | .localhistory/
366 |
367 | # Visual Studio History (VSHistory) files
368 | .vshistory/
369 |
370 | # BeatPulse healthcheck temp database
371 | healthchecksdb
372 |
373 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
374 | MigrationBackup/
375 |
376 | # Ionide (cross platform F# VS Code tools) working folder
377 | .ionide/
378 |
379 | # Fody - auto-generated XML schema
380 | FodyWeavers.xsd
381 |
382 | # VS Code files for those working on multiple tools
383 | .vscode/*
384 | !.vscode/settings.json
385 | !.vscode/tasks.json
386 | !.vscode/launch.json
387 | !.vscode/extensions.json
388 | *.code-workspace
389 |
390 | # Local History for Visual Studio Code
391 | .history/
392 |
393 | # Windows Installer files from build outputs
394 | *.cab
395 | *.msi
396 | *.msix
397 | *.msm
398 | *.msp
399 |
400 | # JetBrains Rider
401 | *.sln.iml
402 |
403 | # End of https://www.toptal.com/developers/gitignore/api/csharp
--------------------------------------------------------------------------------
/umjunsik-lang-csharp/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Linq;
4 | using System.Collections.Generic;
5 |
6 | Bootstrap(/*"../../../../examples/pyramid.umm");//*/args[0]);
7 |
8 | void Bootstrap(string filePath)
9 | {
10 | try
11 | {
12 | if (File.Exists(filePath))
13 | Run(File.ReadAllText(filePath));
14 | }
15 | catch (IOException)
16 | {
17 | throw new Exception($"{filePath}가 어떻게 파일이름이냐ㅋㅋ");
18 | }
19 | };
20 |
21 | void Run (string content) {
22 | var proceed = content.TrimEnd().Split("\n").Select(x => x.Trim()).ToArray();
23 | if (!(proceed[0] == "어떻게" && proceed[^1] == "이 사람이름이냐ㅋㅋ"))
24 | throw new Exception("어떻게 이 코드가 엄랭이냐ㅋㅋ");
25 | var variables = new Dictionary();
26 | if (content.Contains("~")) proceed = content.Split("~");
27 | var pointer = 1;
28 |
29 | while (proceed[pointer] != "이 사람이름이냐ㅋㅋ")
30 | {
31 | var operation = proceed[pointer++];
32 | var evaludated = ParseOperation(operation);
33 | if (evaludated != null)
34 | Environment.Exit(evaludated.Value);
35 | }
36 |
37 | int? ParseOperation(string operation)
38 | {
39 | if (operation.Contains("동탄") && operation.Contains("?"))
40 | {
41 | var condition = Numberify(
42 | SubStringJs(operation, 2, operation.LastIndexOf("?") + 1)
43 | );
44 | if (condition == 0)
45 | return ParseOperation(operation.Substring(operation.LastIndexOf("?") + 1));
46 | return null;
47 | }
48 | if (operation.Contains('엄'))
49 | {
50 | var a = operation.Split('엄');
51 | var variablePointer = operation.Split('엄')[0].Count(x => x == '어');
52 | var setteeValue = Numberify(operation.Split('엄')[1]);
53 | if (variables.ContainsKey(variablePointer))
54 | variables[variablePointer] = setteeValue;
55 | else
56 | variables.Add(variablePointer, setteeValue);
57 | }
58 | if (operation.Contains('식') && operation[^1] == '!')
59 | Console.Write(Numberify(operation[1..^1]));
60 | if (operation.Contains('식') && operation[^1] == 'ㅋ')
61 | {
62 | if (operation == "식ㅋ") Console.WriteLine();
63 | Console.Write((char)Numberify(operation[1..^1]));
64 | }
65 | if (operation.Contains('준'))
66 | {
67 | pointer = Numberify(operation.Split('준')[1]) - 1;
68 | }
69 | if (operation.IndexOf("화이팅!") == 0)
70 | return Numberify(operation.Split("화이팅!")[1]);
71 | return null;
72 |
73 | int Numberify(string a)
74 | {
75 | var numbered = 0;
76 | if (a.Contains(" "))
77 | return a.Split(" ").Select(x => Numberify(x)).Aggregate((a, b) => a * b);
78 | if (a.Contains("식?"))
79 | a = a.Replace("식?", string.Concat(Enumerable.Repeat(".", int.Parse(Console.ReadLine()))));
80 |
81 | var index = a.Count(x => x == '어') - 1;
82 | if (variables.ContainsKey(index))
83 | if (a.Contains('어')) numbered += variables[index];
84 | if (a.Contains('.')) numbered += a.Count(x => x == '.');
85 | if (a.Contains(',')) numbered -= a.Count(x => x == ',');
86 | return numbered;
87 | }
88 |
89 | string SubStringJs(string str, int from, int to)
90 | {
91 | if (from == to) return string.Empty;
92 | if (to < from)
93 | {
94 | var t = from;
95 | from = to;
96 | to = t;
97 | }
98 | return str.Substring(from, to - from);
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/umjunsik-lang-csharp/umjunsik-lang-csharp.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net6.0
6 | umjunsik_lang_csharp
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/umjunsik-lang-csharp/umjunsik-lang-csharp.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.31507.150
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "umjunsik-lang-csharp", "umjunsik-lang-csharp.csproj", "{53CAE929-82BE-4F94-8A57-9F8CCF2C375A}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {53CAE929-82BE-4F94-8A57-9F8CCF2C375A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {53CAE929-82BE-4F94-8A57-9F8CCF2C375A}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {53CAE929-82BE-4F94-8A57-9F8CCF2C375A}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {53CAE929-82BE-4F94-8A57-9F8CCF2C375A}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {4801A51B-6747-4D82-A84A-2074C45AB231}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/umjunsik-lang-deno/index.ts:
--------------------------------------------------------------------------------
1 | import { readLines } from "https://deno.land/std@v0.68.0/io/bufio.ts";
2 |
3 | export const run = async (content: string) => {
4 | let proceed = content.split("\n");
5 | const encoder = new TextEncoder();
6 | if (
7 | !(proceed[0] === "어떻게" && proceed.slice(-1)[0] === "이 사람이름이냐!")
8 | ) {
9 | new Error("어떻게 이 코드가 엄랭이냐ㅋㅋ");
10 | }
11 | const variables: number[] = [];
12 | if (content.includes("~")) proceed = content.split("~");
13 | let pointer = 0;
14 | const numberify = async (a: string): Promise => {
15 | let numbered = 0;
16 | if (a.includes(" "))
17 | return (await Promise.all(a.split(" ").map(numberify))).reduce(
18 | (a, b) => a * b
19 | );
20 | if (a.includes("식?")) {
21 | for await (const line of readLines(Deno.stdin)) {
22 | a = a.replace("식?", ".".repeat(Number(line)));
23 | break;
24 | }
25 | }
26 | if (a.includes("어")) numbered += variables[a.split("어").length - 1];
27 | if (a.includes(".")) numbered += a.split(".").length - 1;
28 | if (a.includes(",")) numbered -= a.split(",").length - 1;
29 | return numbered;
30 | };
31 | const stringify = (unicode: number) => {
32 | return String.fromCharCode(unicode);
33 | };
34 |
35 | const parseOperation = async (
36 | operation: string
37 | ): Promise => {
38 | if (operation.includes("동탄") && operation.includes("?")) {
39 | //IFGOTO
40 | const condition = await numberify(
41 | operation.substring(2, operation.lastIndexOf("?") + 1)
42 | );
43 | if (condition === 0) {
44 | return parseOperation(operation.substr(operation.lastIndexOf("?") + 1));
45 | }
46 | return;
47 | }
48 | if (operation.includes("엄")) {
49 | const variablePointer = operation.split("엄")[0].split("어").length;
50 | const setteeValue = await numberify(operation.split("엄")[1]);
51 | variables[variablePointer] = setteeValue;
52 | }
53 | if (operation.includes("식") && operation[operation.length - 1] === "!") {
54 | await Deno.stdout.write(
55 | encoder.encode(String(await numberify(operation.slice(1, -1))))
56 | );
57 | }
58 | if (operation.includes("식") && operation[operation.length - 1] === "ㅋ") {
59 | if (operation === "식ㅋ") console.log();
60 | await Deno.stdout.write(
61 | encoder.encode(stringify(await numberify(operation.slice(1, -1))))
62 | );
63 | }
64 | if (operation.includes("준")) {
65 | pointer = (await numberify(operation.split("준")[1])) - 1;
66 | }
67 | if (operation.indexOf("화이팅!") === 0) {
68 | return numberify(operation.split("화이팅!")[1]);
69 | }
70 | };
71 |
72 | while (proceed[pointer] !== "이 사람이름이냐!") {
73 | const operation = proceed[pointer++];
74 | const evaludated = await parseOperation(operation);
75 | if (evaludated) return evaludated;
76 | }
77 | };
78 |
79 | const bootstrap = async (filepath: string) => {
80 | try {
81 | if (await Deno.stat(filepath)) run(await Deno.readTextFile(filepath));
82 | } catch (e) {
83 | new Error(`${filepath}가 어떻게 파일이름이냐ㅋㅋ`);
84 | }
85 | };
86 |
87 | if (Deno.args[0]) bootstrap(Deno.args[0]);
88 |
--------------------------------------------------------------------------------
/umjunsik-lang-deno/readme.md:
--------------------------------------------------------------------------------
1 | # 엄랭 Deno 구현체
2 |
3 | ## How to run?
4 |
5 | `deno run --allow-read --unstable .\index.ts filename`
6 |
7 | ## 업데이트 로그
8 |
9 | - 20200625 : 엄랭v1-엄랭디노v2
10 | - 엄랭디노의 첫 버전입니다
11 | - 20200804 : 엄랭v2-엄랭디노v2
12 | - **엄랭v2 변경점 반영**
13 | - `,` 키워드가 정상적으로 작동하지 않는 이슈 해결
14 | - `while` 안에 인라인으로 작성되었던 코드분석 코드를 `parseOperation`함수로 분리
15 | - `어떻게`로 시작하고 `이 사람이름이냐!`로 끝나야만 실행되어야했지만, 그 반대여서 어떤 프로그램도 실행하지 못했던 오류 수정
16 | - 20200805 : 엄랭v2-엄랭디노v2.1
17 | - 전까지는 두 수의 곱셈만 가능했지만, 이제는 공백으로 연결된 수많은 수를 곱할 수 있습니다
18 | - 20200912 : 엄랭v2-엄랭디노v2.1.1
19 | - 여러 디노 버전에 대응하기 위해 std/fs 의존성 제거
20 | - 이하 변경사항은 code styling
21 |
--------------------------------------------------------------------------------
/umjunsik-lang-go/ast/ast.go:
--------------------------------------------------------------------------------
1 | package ast
2 |
3 | import (
4 | "bytes"
5 | "strconv"
6 | "umjunsik-lang/umjunsik-lang-go/token"
7 | )
8 |
9 | type Node interface {
10 | TokenLiteral() string
11 | String() string
12 | }
13 |
14 | type Line interface {
15 | Node
16 | lineNode()
17 | }
18 |
19 | type Expression interface {
20 | Node
21 | expressionNode()
22 | }
23 |
24 | type Program struct {
25 | Lines []Line
26 | }
27 |
28 | func (p *Program) TokenLiteral() string {
29 | if len(p.Lines) > 0 {
30 | return p.Lines[0].TokenLiteral()
31 | } else {
32 | return ""
33 | }
34 | }
35 |
36 | func (p *Program) String() string {
37 | var out bytes.Buffer
38 |
39 | for i, s := range p.Lines {
40 | out.WriteString(strconv.Itoa(i) + ". ")
41 | out.WriteString(s.String())
42 | out.WriteString("\n")
43 | }
44 |
45 | return out.String()
46 | }
47 |
48 | type ExpressionLine struct {
49 | Token token.Token
50 | Expression Expression
51 | }
52 |
53 | func (el *ExpressionLine) lineNode() {}
54 | func (el *ExpressionLine) TokenLiteral() string { return el.Token.Literal }
55 | func (el *ExpressionLine) String() string {
56 | if el.Expression != nil {
57 | return el.Expression.String()
58 | }
59 | return ""
60 | }
61 |
62 | type InfixIntegerExpression struct {
63 | Token token.Token
64 | Left Expression
65 | Right int64
66 | }
67 |
68 | func (ie *InfixIntegerExpression) expressionNode() {}
69 | func (ie *InfixIntegerExpression) TokenLiteral() string { return ie.Token.Literal }
70 | func (ie *InfixIntegerExpression) String() string {
71 | var out bytes.Buffer
72 |
73 | out.WriteString("(")
74 | out.WriteString(ie.Left.String())
75 | out.WriteString(" + " + strconv.Itoa(int(ie.Right)))
76 | out.WriteString(")")
77 |
78 | return out.String()
79 | }
80 |
81 | type SPACEExpression struct {
82 | Token token.Token
83 | Left Expression
84 | Right Expression
85 | }
86 |
87 | func (se *SPACEExpression) expressionNode() {}
88 | func (se *SPACEExpression) TokenLiteral() string { return se.Token.Literal }
89 | func (se *SPACEExpression) String() string {
90 | var out bytes.Buffer
91 |
92 | out.WriteString("(")
93 | out.WriteString(se.Left.String())
94 | out.WriteString(" * " + se.Right.String())
95 | out.WriteString(")")
96 |
97 | return out.String()
98 | }
99 |
100 | type IntegerLiteral struct {
101 | Token token.Token
102 | Value int64
103 | }
104 |
105 | func (il *IntegerLiteral) expressionNode() {}
106 | func (il *IntegerLiteral) TokenLiteral() string { return il.Token.Literal }
107 | func (il *IntegerLiteral) String() string {
108 | var out bytes.Buffer
109 |
110 | for i := 0; i < int(il.Value); i++ {
111 | out.WriteString(".")
112 | }
113 |
114 | for i := 0; i > int(il.Value); i-- {
115 | out.WriteString(",")
116 | }
117 |
118 | return out.String()
119 | }
120 |
121 | type UEpxression struct {
122 | Token token.Token
123 | Index int64
124 | }
125 |
126 | func (ue *UEpxression) expressionNode() {}
127 | func (ue *UEpxression) TokenLiteral() string { return ue.Token.Literal }
128 | func (ue *UEpxression) String() string {
129 | var out bytes.Buffer
130 |
131 | for i := 0; i < int(ue.Index+1); i++ {
132 | out.WriteString("어")
133 | }
134 |
135 | return out.String()
136 | }
137 |
138 | type UMExpression struct {
139 | Token token.Token
140 | Index int64
141 | Value Expression
142 | }
143 |
144 | func (ume *UMExpression) expressionNode() {}
145 | func (ume *UMExpression) TokenLiteral() string { return ume.Token.Literal }
146 | func (ume *UMExpression) String() string {
147 | var out bytes.Buffer
148 |
149 | for i := 0; i < int(ume.Index); i++ {
150 | out.WriteString("어")
151 | }
152 |
153 | out.WriteString("엄")
154 | out.WriteString(ume.Value.String())
155 |
156 | return out.String()
157 | }
158 |
159 | type JUNEExpression struct {
160 | Token token.Token
161 | Index Expression
162 | }
163 |
164 | func (je *JUNEExpression) expressionNode() {}
165 | func (je *JUNEExpression) TokenLiteral() string { return je.Token.Literal }
166 | func (je *JUNEExpression) String() string {
167 | var out bytes.Buffer
168 |
169 | out.WriteString("준")
170 |
171 | out.WriteString(je.Index.String())
172 |
173 | return out.String()
174 | }
175 |
176 | type SIKQExpression struct {
177 | Token token.Token
178 | }
179 |
180 | func (sqe *SIKQExpression) expressionNode() {}
181 | func (sqe *SIKQExpression) TokenLiteral() string { return sqe.Token.Literal }
182 | func (sqe *SIKQExpression) String() string {
183 | return "식?"
184 | }
185 |
186 | type SIKKIExpression struct {
187 | Token token.Token
188 | Value Expression
189 | }
190 |
191 | func (ske *SIKKIExpression) expressionNode() {}
192 | func (ske *SIKKIExpression) TokenLiteral() string { return ske.Token.Literal }
193 | func (ske *SIKKIExpression) String() string {
194 | var out bytes.Buffer
195 |
196 | out.WriteString("식")
197 | out.WriteString(ske.Value.String())
198 | out.WriteString("ㅋ")
199 |
200 | return out.String()
201 | }
202 |
203 | type SIKBExpression struct {
204 | Token token.Token
205 | Value Expression
206 | }
207 |
208 | func (sbe *SIKBExpression) expressionNode() {}
209 | func (sbe *SIKBExpression) TokenLiteral() string { return sbe.Token.Literal }
210 | func (sbe *SIKBExpression) String() string {
211 | var out bytes.Buffer
212 |
213 | out.WriteString("식")
214 | out.WriteString(sbe.Value.String())
215 | out.WriteString("!")
216 |
217 | return out.String()
218 | }
219 |
220 | type DONGTANExpression struct {
221 | Token token.Token
222 | Condition Expression
223 | Statement Expression
224 | }
225 |
226 | func (de *DONGTANExpression) expressionNode() {}
227 | func (de *DONGTANExpression) TokenLiteral() string { return de.Token.Literal }
228 | func (de *DONGTANExpression) String() string {
229 | var out bytes.Buffer
230 |
231 | out.WriteString("동탄")
232 | out.WriteString(de.Condition.String())
233 | out.WriteString("?")
234 | out.WriteString(de.Statement.String())
235 |
236 | return out.String()
237 | }
238 |
239 | type FIGHTINGExpression struct {
240 | Token token.Token
241 | Value Expression
242 | }
243 |
244 | func (fe *FIGHTINGExpression) expressionNode() {}
245 | func (fe *FIGHTINGExpression) TokenLiteral() string { return fe.Token.Literal }
246 | func (fe *FIGHTINGExpression) String() string {
247 | var out bytes.Buffer
248 |
249 | out.WriteString("화이팅!")
250 | out.WriteString(fe.Value.String())
251 |
252 | return out.String()
253 | }
254 |
--------------------------------------------------------------------------------
/umjunsik-lang-go/eval/eval.go:
--------------------------------------------------------------------------------
1 | package eval
2 |
3 | import (
4 | "fmt"
5 | "os"
6 | "umjunsik-lang/umjunsik-lang-go/ast"
7 | "umjunsik-lang/umjunsik-lang-go/object"
8 | )
9 |
10 | func Eval(node ast.Node, env *object.Environment) object.Object {
11 | switch node := node.(type) {
12 | case *ast.Program:
13 | return evalProgram(node, env)
14 | case *ast.ExpressionLine:
15 | return Eval(node.Expression, env)
16 | case *ast.InfixIntegerExpression:
17 | leftObj := Eval(node.Left, env)
18 | return &object.Integer{Value: leftObj.(*object.Integer).Value + node.Right}
19 | case *ast.SPACEExpression:
20 | leftObj := Eval(node.Left, env)
21 | rightObj := Eval(node.Right, env)
22 | return &object.Integer{Value: leftObj.(*object.Integer).Value * rightObj.(*object.Integer).Value}
23 | case *ast.IntegerLiteral:
24 | return &object.Integer{Value: node.Value}
25 | case *ast.UEpxression:
26 | obj, ok := env.Get(int(node.Index))
27 | if !ok {
28 | return newError("ObjectFindError")
29 | }
30 |
31 | return obj
32 | case *ast.UMExpression:
33 | obj := Eval(node.Value, env)
34 | env.Set(int(node.Index), obj)
35 | case *ast.JUNEExpression:
36 | obj := Eval(node.Index, env)
37 | return &object.JUN{Index: obj.(*object.Integer).Value}
38 | case *ast.SIKQExpression:
39 | var integer int
40 | fmt.Scanln(&integer)
41 | return &object.Integer{Value: int64(integer)}
42 | case *ast.SIKKIExpression:
43 | obj := Eval(node.Value, env)
44 | fmt.Printf("%c", obj.(*object.Integer).Value)
45 | case *ast.SIKBExpression:
46 | obj := Eval(node.Value, env)
47 | fmt.Printf("%d", obj.(*object.Integer).Value)
48 | case *ast.DONGTANExpression:
49 | conditionObj := Eval(node.Condition, env)
50 | if conditionObj.(*object.Integer).Value == 0 {
51 | return Eval(node.Statement, env)
52 | }
53 | case *ast.FIGHTINGExpression:
54 | obj := Eval(node.Value, env)
55 | os.Exit(int(obj.(*object.Integer).Value))
56 | }
57 |
58 | return nil
59 | }
60 |
61 | func evalProgram(program *ast.Program, env *object.Environment) object.Object {
62 | var result object.Object
63 |
64 | for i := 0; i < len(program.Lines); i++ {
65 | line := program.Lines[i]
66 |
67 | result = Eval(line, env)
68 |
69 | switch result := result.(type) {
70 | case *object.JUN:
71 | i = int(result.Index - 3)
72 | case *object.Error:
73 | return result
74 | }
75 | }
76 |
77 | return result
78 | }
79 |
--------------------------------------------------------------------------------
/umjunsik-lang-go/eval/util.go:
--------------------------------------------------------------------------------
1 | package eval
2 |
3 | import (
4 | "fmt"
5 | "umjunsik-lang/umjunsik-lang-go/object"
6 | )
7 |
8 | func isError(obj object.Object) bool {
9 | if obj != nil {
10 | return obj.Type() == object.ERROR_OBJ
11 | }
12 | return false
13 | }
14 |
15 | func newError(format string, a ...interface{}) *object.Error {
16 | return &object.Error{Message: fmt.Sprintf(format, a...)}
17 | }
18 |
--------------------------------------------------------------------------------
/umjunsik-lang-go/go.mod:
--------------------------------------------------------------------------------
1 | module umjunsik-lang/umjunsik-lang-go
2 |
3 | go 1.17
4 |
--------------------------------------------------------------------------------
/umjunsik-lang-go/lexer/lexer.go:
--------------------------------------------------------------------------------
1 | package lexer
2 |
3 | import (
4 | "umjunsik-lang/umjunsik-lang-go/token"
5 | )
6 |
7 | type Lexer struct {
8 | input string
9 | position int
10 | readPosition int
11 | ch string
12 | }
13 |
14 | func New(input string) *Lexer {
15 | l := &Lexer{input: input}
16 | l.readChar()
17 | if l.ch == "어" {
18 | l.readChar()
19 | if l.ch == "떻" {
20 | l.readChar()
21 | if l.ch == "게" {
22 | l.readChar()
23 | } else {
24 | return nil
25 | }
26 | } else {
27 | return nil
28 | }
29 | } else {
30 | return nil
31 | }
32 | return l
33 | }
34 |
35 | func (l *Lexer) NextToken() token.Token {
36 | var tok token.Token
37 |
38 | l.skipWhiteSpace()
39 |
40 | switch l.ch {
41 | case "어":
42 | tok = newToken(token.U, "어")
43 | case "엄":
44 | tok = newToken(token.UM, "엄")
45 | case "준":
46 | tok = newToken(token.JUN, "준")
47 | case "식":
48 | tok = newToken(token.SIK, "식")
49 | case "동":
50 | if l.peekchar() == "탄" {
51 | tok = newToken(token.DONGTAN, "동탄")
52 | l.readChar()
53 | }
54 | case "ㅋ":
55 | tok = newToken(token.KI, "ㅋ")
56 | case "화":
57 | if l.peekchar() == "이" {
58 | l.readChar()
59 | if l.peekchar() == "팅" {
60 | l.readChar()
61 | tok = newToken(token.FIGHTING, "화이팅")
62 | }
63 | }
64 | case ".":
65 | tok = newToken(token.PERIOD, ".")
66 | case ",":
67 | tok = newToken(token.COMMA, ",")
68 | case "?":
69 | tok = newToken(token.QUESTION, "?")
70 | case "!":
71 | tok = newToken(token.BANG, "!")
72 | case "~":
73 | tok = newToken(token.NEWLINE, "~")
74 | case "\n":
75 | tok = newToken(token.NEWLINE, "\n")
76 | case " ":
77 | tok = newToken(token.SPACE, " ")
78 | case "이":
79 | if l.IsLast() {
80 | tok = newToken(token.EOF, "")
81 | return tok
82 | }
83 | }
84 |
85 | l.readChar()
86 | return tok
87 | }
88 |
89 | func newToken(tokenType token.TokenType, ch string) token.Token {
90 | return token.Token{Type: tokenType, Literal: ch}
91 | }
92 |
93 | // UTF-8 인코딩에 따라 문자를 읽습니다.
94 | func (l *Lexer) readChar() {
95 | Byte1 := l.input[l.readPosition]
96 |
97 | if Byte1 >= 128 {
98 | l.ch = string([]byte{Byte1, l.input[l.readPosition+1], l.input[l.readPosition+2]})
99 |
100 | l.position = l.readPosition
101 | l.readPosition += 3
102 | } else {
103 | l.ch = string(Byte1)
104 | l.position = l.readPosition
105 | l.readPosition += 1
106 | }
107 | }
108 |
109 | func (l *Lexer) peekchar() string {
110 | if l.input[l.readPosition] >= 128 {
111 | return string([]byte{l.input[l.readPosition], l.input[l.readPosition+1], l.input[l.readPosition+2]})
112 | } else {
113 | return string(l.input[l.readPosition])
114 | }
115 | }
116 |
117 | func (l *Lexer) skipWhiteSpace() {
118 | if l.ch == "\r" || l.ch == "\t" || l.ch == "\v" || l.ch == "\f" {
119 | l.readChar()
120 | }
121 | }
122 |
123 | func (l *Lexer) IsLast() bool {
124 | return l.input[l.position:l.position+28] == "이 사람이름이냐ㅋㅋ"
125 | }
126 |
--------------------------------------------------------------------------------
/umjunsik-lang-go/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 | "io/ioutil"
6 | "umjunsik-lang/umjunsik-lang-go/eval"
7 | "umjunsik-lang/umjunsik-lang-go/lexer"
8 | "umjunsik-lang/umjunsik-lang-go/object"
9 | "umjunsik-lang/umjunsik-lang-go/parser"
10 | )
11 |
12 | var (
13 | FilePath string
14 | )
15 |
16 | func init() {
17 | flag.Parse()
18 | FilePath = flag.Args()[0]
19 | }
20 |
21 | func main() {
22 | Code, err := ioutil.ReadFile(FilePath)
23 | if err != nil {
24 | panic(err)
25 | }
26 | Interpret(Code)
27 | }
28 |
29 | func Interpret(Code []byte) {
30 | l := lexer.New(string(Code))
31 | p := parser.New(l)
32 | program := p.ParseProgram()
33 | env := object.NewEnvironment()
34 | eval.Eval(program, env)
35 |
36 | // for tok := l.NextToken(); tok.Type != token.EOF; tok = l.NextToken() {
37 | // fmt.Println("{" + " Type : " + string(tok.Type) + ", Literal : " + tok.Literal + " }")
38 | //}
39 | }
40 |
--------------------------------------------------------------------------------
/umjunsik-lang-go/object/object.go:
--------------------------------------------------------------------------------
1 | package object
2 |
3 | import "strconv"
4 |
5 | type Environment struct {
6 | store map[int]Object
7 | }
8 |
9 | func NewEnvironment() *Environment {
10 | s := make(map[int]Object)
11 | return &Environment{store: s}
12 | }
13 |
14 | func (env *Environment) Get(index int) (Object, bool) {
15 | obj, ok := env.store[index]
16 | if !ok {
17 | obj = &Integer{Value: 0}
18 | }
19 | return obj, true
20 | }
21 |
22 | func (env *Environment) Set(index int, obj Object) {
23 | env.store[index] = obj
24 | }
25 |
26 | const (
27 | JUN_OBJ = "JUN_OBJ"
28 | INTEGER_OBJ = "INTEGER_OBJ"
29 | ERROR_OBJ = "ERROR_OBJ"
30 | )
31 |
32 | type ObjectType string
33 |
34 | type Object interface {
35 | Type() ObjectType
36 | Inspect() string
37 | }
38 |
39 | type JUN struct {
40 | Index int64
41 | }
42 |
43 | func (j *JUN) Type() ObjectType { return JUN_OBJ }
44 | func (j *JUN) Inspect() string { return strconv.Itoa(int(j.Index)) }
45 |
46 | type Integer struct {
47 | Value int64
48 | }
49 |
50 | func (i *Integer) Type() ObjectType { return INTEGER_OBJ }
51 | func (i *Integer) Inspect() string { return strconv.Itoa(int(i.Value)) }
52 |
53 | type Error struct {
54 | Message string
55 | }
56 |
57 | func (e *Error) Type() ObjectType { return ERROR_OBJ }
58 | func (e *Error) Inspect() string { return "ERROR: " + e.Message }
59 |
--------------------------------------------------------------------------------
/umjunsik-lang-go/parser/parser.go:
--------------------------------------------------------------------------------
1 | package parser
2 |
3 | import (
4 | "umjunsik-lang/umjunsik-lang-go/ast"
5 | "umjunsik-lang/umjunsik-lang-go/lexer"
6 | "umjunsik-lang/umjunsik-lang-go/token"
7 | )
8 |
9 | type Parser struct {
10 | l *lexer.Lexer
11 | errors []string
12 |
13 | curToken token.Token
14 | peekToken token.Token
15 |
16 | prefixParseFns map[token.TokenType]prefixParseFn
17 | infixParseFns map[token.TokenType]infixParseFn
18 | }
19 |
20 | type (
21 | prefixParseFn func() ast.Expression
22 | infixParseFn func(ast.Expression) ast.Expression
23 | )
24 |
25 | func (p *Parser) registerPrefix(tokenType token.TokenType, fn prefixParseFn) {
26 | p.prefixParseFns[tokenType] = fn
27 | }
28 |
29 | func (p *Parser) registerInfix(tokenType token.TokenType, fn infixParseFn) {
30 | p.infixParseFns[tokenType] = fn
31 | }
32 |
33 | func New(l *lexer.Lexer) *Parser {
34 | p := &Parser{
35 | l: l,
36 | errors: []string{},
37 | }
38 | p.nextToken()
39 | p.nextToken()
40 |
41 | p.prefixParseFns = make(map[token.TokenType]prefixParseFn)
42 | p.registerPrefix(token.U, p.parseUExpression)
43 | p.registerPrefix(token.PERIOD, p.parsePrefixIntegerExpression)
44 | p.registerPrefix(token.COMMA, p.parsePrefixIntegerExpression)
45 | p.registerPrefix(token.UM, p.parseUMExpression)
46 | p.registerPrefix(token.JUN, p.parseJUNExpression)
47 | p.registerPrefix(token.SIK, p.parseSIKExpression)
48 | p.registerPrefix(token.DONGTAN, p.parseDONGTANExpression)
49 | p.registerPrefix(token.FIGHTING, p.parseFIGHTINGExpression)
50 |
51 | p.infixParseFns = make(map[token.TokenType]infixParseFn)
52 | p.registerInfix(token.PERIOD, p.parseInfixIntegerExpression)
53 | p.registerInfix(token.COMMA, p.parseInfixIntegerExpression)
54 | p.registerInfix(token.SPACE, p.parseSPACEExpression)
55 |
56 | return p
57 | }
58 |
59 | func (p *Parser) ParseProgram() *ast.Program {
60 | program := &ast.Program{}
61 | program.Lines = []ast.Line{}
62 |
63 | for p.curToken.Type != token.EOF {
64 | line := p.parseLine()
65 | program.Lines = append(program.Lines, line)
66 |
67 | p.nextToken()
68 | }
69 |
70 | return program
71 | }
72 |
73 | func (p *Parser) parseLine() ast.Line {
74 | return p.parseExpressionStatement()
75 | }
76 |
77 | func (p *Parser) parseExpressionStatement() *ast.ExpressionLine {
78 | line := &ast.ExpressionLine{Token: p.curToken}
79 | line.Expression = p.parseExpression()
80 |
81 | if p.peekTokenIs(token.NEWLINE) {
82 | p.nextToken()
83 | }
84 |
85 | return line
86 | }
87 |
88 | func (p *Parser) parseExpression() ast.Expression {
89 | prefix := p.prefixParseFns[p.curToken.Type]
90 | if prefix == nil {
91 | p.noPrefixParseFnError(p.curToken.Type)
92 | return nil
93 | }
94 | leftExp := prefix()
95 |
96 | for !(p.peekTokenIs(token.NEWLINE) || p.peekTokenIs(token.KI) || p.peekTokenIs(token.QUESTION) || p.peekTokenIs(token.BANG)) {
97 | infix := p.infixParseFns[p.peekToken.Type]
98 | if infix == nil {
99 | return leftExp
100 | }
101 |
102 | p.nextToken()
103 |
104 | leftExp = infix(leftExp)
105 | }
106 |
107 | return leftExp
108 | }
109 |
110 | func (p *Parser) parseUExpression() ast.Expression {
111 | exp := &ast.UEpxression{Token: p.curToken}
112 |
113 | var index int64 = 0
114 |
115 | for p.peekTokenIs(token.U) {
116 | index++
117 | p.nextToken()
118 | }
119 |
120 | if p.peekTokenIs(token.UM) {
121 | p.nextToken()
122 | exp := &ast.UMExpression{Token: p.curToken}
123 | exp.Index = index + 1
124 |
125 | if p.peekTokenIs(token.NEWLINE) {
126 | if exp.Value == nil {
127 | exp.Value = &ast.IntegerLiteral{
128 | Token: token.Token{
129 | Type: token.PERIOD,
130 | Literal: ".",
131 | },
132 | Value: 0,
133 | }
134 | }
135 | } else {
136 | p.nextToken()
137 | exp.Value = p.parseExpression()
138 | }
139 |
140 | return exp
141 | }
142 |
143 | exp.Index = index
144 |
145 | return exp
146 | }
147 |
148 | func (p *Parser) parseUMExpression() ast.Expression {
149 | if p.curTokenIs(token.UM) {
150 | p.nextToken()
151 | }
152 |
153 | tmp := p.parseExpression()
154 | tok := p.curToken
155 |
156 | if tmp != nil {
157 | return &ast.UMExpression{Token: tok, Index: 0, Value: tmp}
158 | } else {
159 | return &ast.UMExpression{Token: tok, Index: 0, Value: &ast.IntegerLiteral{
160 | Token: token.Token{
161 | Type: token.PERIOD,
162 | Literal: ".",
163 | },
164 | Value: 0,
165 | },
166 | }
167 | }
168 | }
169 |
170 | func (p *Parser) parsePrefixIntegerExpression() ast.Expression {
171 | lit := &ast.IntegerLiteral{Token: p.curToken}
172 |
173 | var result int64 = 0
174 |
175 | if p.curTokenIs(token.PERIOD) {
176 | result++
177 | } else if p.curTokenIs(token.COMMA) {
178 | result--
179 | }
180 |
181 | for p.peekTokenIs(token.PERIOD) || p.peekTokenIs(token.COMMA) {
182 | switch p.peekToken.Type {
183 | case token.PERIOD:
184 | result++
185 | case token.COMMA:
186 | result--
187 | }
188 | p.nextToken()
189 | }
190 |
191 | lit.Value = result
192 |
193 | return lit
194 | }
195 |
196 | func (p *Parser) parseJUNExpression() ast.Expression {
197 | exp := &ast.JUNEExpression{Token: p.curToken}
198 |
199 | if p.peekTokenIs(token.NEWLINE) {
200 | return nil
201 | }
202 |
203 | p.nextToken()
204 |
205 | exp.Index = p.parseExpression()
206 |
207 | return exp
208 | }
209 |
210 | func (p *Parser) parseSIKExpression() ast.Expression {
211 | if p.peekTokenIs(token.QUESTION) {
212 | p.nextToken()
213 | return &ast.SIKQExpression{Token: p.curToken}
214 | }
215 |
216 | p.nextToken()
217 |
218 | // if p.peekTokenIs(token.BANG) {
219 | // p.nextToken()
220 | //}
221 | if p.curTokenIs(token.KI) {
222 | exp := &ast.SIKKIExpression{Token: p.curToken}
223 | exp.Value = &ast.IntegerLiteral{
224 | Token: token.Token{
225 | Type: token.PERIOD,
226 | Literal: ".",
227 | },
228 | Value: 10,
229 | }
230 |
231 | return exp
232 | }
233 |
234 | tem := p.parseExpression()
235 |
236 | switch p.peekToken.Type {
237 | case token.BANG:
238 | p.nextToken()
239 | exp := &ast.SIKBExpression{Token: p.curToken}
240 |
241 | exp.Value = tem
242 | return exp
243 | case token.KI:
244 | p.nextToken()
245 | exp := &ast.SIKKIExpression{Token: p.curToken}
246 | if tem != nil {
247 | exp.Value = tem
248 | }
249 | return exp
250 | }
251 |
252 | return nil
253 | }
254 |
255 | func (p *Parser) parseDONGTANExpression() ast.Expression {
256 | exp := &ast.DONGTANExpression{Token: p.curToken}
257 |
258 | if p.peekTokenIs(token.NEWLINE) {
259 | return nil
260 | }
261 |
262 | p.nextToken()
263 |
264 | exp.Condition = p.parseExpression()
265 |
266 | if !p.expectPeek(token.QUESTION) {
267 | return nil
268 | }
269 |
270 | p.nextToken()
271 |
272 | exp.Statement = p.parseExpression()
273 |
274 | return exp
275 | }
276 |
277 | func (p *Parser) parseFIGHTINGExpression() ast.Expression {
278 | exp := &ast.FIGHTINGExpression{Token: p.curToken}
279 |
280 | if !p.expectPeek(token.BANG) {
281 | return nil
282 | }
283 |
284 | p.nextToken()
285 |
286 | exp.Value = p.parseExpression()
287 |
288 | return exp
289 | }
290 |
291 | func (p *Parser) parseInfixIntegerExpression(left ast.Expression) ast.Expression {
292 | exp := &ast.InfixIntegerExpression{Token: p.curToken, Left: left}
293 |
294 | var result int64 = 0
295 |
296 | if p.curTokenIs(token.PERIOD) {
297 | result++
298 | } else if p.curTokenIs(token.COMMA) {
299 | result--
300 | }
301 |
302 | for p.peekTokenIs(token.PERIOD) || p.peekTokenIs(token.COMMA) {
303 | switch p.curToken.Type {
304 | case token.PERIOD:
305 | result++
306 | case token.COMMA:
307 | result--
308 | }
309 | p.nextToken()
310 | }
311 |
312 | exp.Right = result
313 |
314 | return exp
315 | }
316 |
317 | func (p *Parser) parseSPACEExpression(left ast.Expression) ast.Expression {
318 | exp := &ast.SPACEExpression{Token: p.curToken, Left: left}
319 |
320 | p.nextToken()
321 | exp.Right = p.parseExpression()
322 |
323 | return exp
324 | }
325 |
--------------------------------------------------------------------------------
/umjunsik-lang-go/parser/util.go:
--------------------------------------------------------------------------------
1 | package parser
2 |
3 | import (
4 | "fmt"
5 | "umjunsik-lang/umjunsik-lang-go/token"
6 | )
7 |
8 | func (p *Parser) Errors() []string {
9 | return p.errors
10 | }
11 |
12 | func (p *Parser) noPrefixParseFnError(t token.TokenType) {
13 | msg := fmt.Sprintf("no prefix parse function for %s found", t)
14 | p.errors = append(p.errors, msg)
15 | }
16 |
17 | func (p *Parser) peekError(t token.TokenType) {
18 | msg := fmt.Sprintf("expected next token to be %s, got %s instend", t, p.peekToken.Type)
19 | p.errors = append(p.errors, msg)
20 | }
21 |
22 | func (p *Parser) nextToken() {
23 | p.curToken = p.peekToken
24 | p.peekToken = p.l.NextToken()
25 | }
26 |
27 | // 다음 토큰을 검사하고 이동하므로 안전한 토큰 이동입니다.
28 | func (p *Parser) expectPeek(t token.TokenType) bool {
29 | if p.peekTokenIs(t) {
30 | p.nextToken()
31 | return true
32 | } else {
33 | p.peekError(t)
34 | return false
35 | }
36 | }
37 |
38 | func (p *Parser) curTokenIs(t token.TokenType) bool {
39 | return p.curToken.Type == t
40 | }
41 |
42 | func (p *Parser) peekTokenIs(t token.TokenType) bool {
43 | return p.peekToken.Type == t
44 | }
45 |
--------------------------------------------------------------------------------
/umjunsik-lang-go/token/token.go:
--------------------------------------------------------------------------------
1 | package token
2 |
3 | type TokenType string
4 |
5 | type Token struct {
6 | Type TokenType
7 | Literal string
8 | }
9 |
10 | const (
11 | ILLEGAL = "ILLEGAL"
12 | EOF = "EOF"
13 |
14 | U = "U"
15 | UM = "UM"
16 | JUN = "JUN"
17 | SIK = "SIK"
18 | DONGTAN = "DONGTAN"
19 | KI = "KI"
20 | NEWLINE = "NEWLINE"
21 | FIGHTING = "FIGHTING"
22 | PERIOD = "."
23 | COMMA = ","
24 | BANG = "!"
25 | QUESTION = "?"
26 | SPACE = " "
27 | )
28 |
--------------------------------------------------------------------------------
/umjunsik-lang-java/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rycont/umjunsik-lang/e973f9d22b9803ee86b53d8e60f1b65ab08c7547/umjunsik-lang-java/.DS_Store
--------------------------------------------------------------------------------
/umjunsik-lang-java/main.java:
--------------------------------------------------------------------------------
1 | import setting.Items;
2 | import setting.console.ChangeUni;
3 | import setting.console.Print;
4 | import setting.console.Scan;
5 | import setting.var.VarGet;
6 | import setting.var.VarSet;
7 |
8 | import java.io.BufferedReader;
9 | import java.io.FileReader;
10 | import java.io.IOException;
11 | import java.nio.charset.Charset;
12 | import java.nio.charset.StandardCharsets;
13 | import java.nio.file.Files;
14 | import java.nio.file.Path;
15 | import java.nio.file.Paths;
16 | import java.util.List;
17 | import java.util.Locale;
18 |
19 | public class main extends Items {
20 |
21 | public static void main(String[] args) throws IOException {
22 | TotalText = "";
23 |
24 | // Path path = Paths.get("./" + "test.umm");
25 | // Charset cs = StandardCharsets.UTF_8;
26 | // List list = Files.readAllLines(path, cs);
27 | // list.forEach(main::first);
28 |
29 | String fileName = args[0];
30 | if (fileName.toLowerCase(Locale.ROOT).endsWith(".umm")) throw new IOException("확장자가 일치하지 않습니다.");
31 | BufferedReader reader = new BufferedReader(new FileReader(fileName, StandardCharsets.UTF_8));
32 | String readerString;
33 | while ((readerString = reader.readLine()) != null) first(readerString);
34 | reader.close();
35 |
36 | int startPos = TotalText.indexOf("어떻게") + 3;
37 | int endPos = TotalText.lastIndexOf("이 사람이름이냐ㅋㅋ");
38 | TotalText = TotalText.substring(startPos, endPos);
39 |
40 | ChangeUni changeUni = new ChangeUni();
41 | Print print = new Print();
42 | Scan scan = new Scan();
43 | VarGet varGet = new VarGet();
44 | VarSet varSet = new VarSet();
45 |
46 | String[] lines = TotalText.split("\\n");
47 | for (String line : lines) {
48 | // System.out.println(line);
49 | if (changeUni.check(line)) changeUni.change(line);
50 | else if (print.check(line)) print.print(line);
51 | else if (scan.check(line)) scan.scanner(line);
52 | else if (varGet.check(line)) varGet.get(line);
53 | else if (varSet.check(line)) varSet.set(line);
54 | }
55 | }
56 |
57 | private static void first(String line) {
58 | TotalText += (line + "\n");
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/umjunsik-lang-java/setting/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rycont/umjunsik-lang/e973f9d22b9803ee86b53d8e60f1b65ab08c7547/umjunsik-lang-java/setting/.DS_Store
--------------------------------------------------------------------------------
/umjunsik-lang-java/setting/Count.java:
--------------------------------------------------------------------------------
1 | package setting;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | public class Count {
7 | int totalNumber = 0;
8 |
9 | //계산 후 반환
10 | public int count(String line) {
11 | totalNumber = 0;
12 | String[] texts = line.split(" ");
13 | List list = new ArrayList<>();
14 |
15 | for (String text : texts) {
16 | int count = 0;
17 | for (int i = 0; i totalNumber *= number);
28 | return totalNumber;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/umjunsik-lang-java/setting/Items.java:
--------------------------------------------------------------------------------
1 | package setting;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | public class Items {
7 | public static String TotalText;
8 | public static Map map = new HashMap<>();
9 | }
--------------------------------------------------------------------------------
/umjunsik-lang-java/setting/console/ChangeUni.java:
--------------------------------------------------------------------------------
1 | package setting.console;
2 |
3 | import setting.var.VarGet;
4 |
5 | public class ChangeUni {
6 |
7 | public void change(String line) {
8 | int start = line.indexOf("식") + 1;
9 | int end = line.lastIndexOf("ㅋ");
10 | line = line.substring(start, end);
11 |
12 | VarGet varGet = new VarGet();
13 | if (line.isBlank()) System.out.println();
14 | else {
15 | int i = varGet.get(line);
16 | System.out.print((char) i);
17 | }
18 | }
19 |
20 | public boolean check(String line) {
21 | if (line.isBlank()) return false;
22 | return line.trim().startsWith("식") && line.endsWith("ㅋ");
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/umjunsik-lang-java/setting/console/Print.java:
--------------------------------------------------------------------------------
1 | package setting.console;
2 |
3 | import setting.var.VarGet;
4 |
5 | public class Print {
6 |
7 | public void print(String line) {
8 |
9 | int start = line.indexOf("식") + 1;
10 | int end = line.lastIndexOf("!");
11 |
12 | line = line.substring(start, end);
13 | VarGet varGet = new VarGet();
14 | System.out.print(varGet.get(line));
15 | }
16 |
17 | public boolean check(String line) {
18 | return line.trim().startsWith("식") && line.endsWith("!");
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/umjunsik-lang-java/setting/console/Scan.java:
--------------------------------------------------------------------------------
1 | package setting.console;
2 |
3 | import setting.var.VarSet;
4 |
5 | import java.util.Scanner;
6 |
7 | public class Scan {
8 | public void scanner(String line) {
9 | Scanner sc = new Scanner(System.in);
10 | int getInt = sc.nextInt();
11 | VarSet varSet = new VarSet();
12 | varSet.set(line, getInt);
13 | }
14 |
15 | public boolean check(String line) {
16 | return line.trim().endsWith("식?");
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/umjunsik-lang-java/setting/var/VarGet.java:
--------------------------------------------------------------------------------
1 | package setting.var;
2 |
3 | import setting.Count;
4 | import setting.Items;
5 |
6 | public class VarGet {
7 | //어..
8 | public int get(String line) {
9 | Count count = new Count();
10 | return count.count(changeVar(line.trim()));
11 | }
12 |
13 | public boolean check(String text) {
14 | return text.contains("어");
15 | }
16 |
17 | //변수 -> 값
18 | private String changeVar(String line) {
19 | int len = line.trim().replaceAll("[.|,]", "").length();
20 | for (int i = len; i>0; i--) {
21 | String key = getKey(i);
22 | if (line.contains(key)) line = line.replace(key, Items.map.get(i));
23 | } return line;
24 | }
25 |
26 | private String getKey(int len) {
27 | String total = "";
28 | for (int i = 0; i = mutableListOf()
10 |
11 | var pc: Int = 0
12 |
13 | fun MutableList.getSafe(index: Int): Int {
14 | return if(index > this.lastIndex) 0 else this[index]
15 | }
16 |
17 | fun MutableList.setSafe(index: Int, value: Int) {
18 | if(index > this.lastIndex){
19 | for(i in 0 until index - this.lastIndex){
20 | this.add(0)
21 | }
22 | }
23 | this[index] = value
24 | }
25 |
26 | fun parseLine(code: String){
27 | if(code.startsWith("화이팅!")){
28 | exitProcess(memory.getSafe(code.replace("화이팅!", "").toUmmInt()))
29 | }
30 | else if(code.endsWith("식?")){
31 | if(code.replace("식?", "") == ""){
32 | throw java.lang.RuntimeException("문법 오류: 대입할 변수 미지정 (${pc + 1}번 줄)")
33 | }
34 | else {
35 | val sc = Scanner(System.`in`)
36 | memory.setSafe(code.replace("식?", "").toUmmInt(), sc.nextInt())
37 | }
38 | }
39 | else if(code.startsWith("식")){
40 | if(code.endsWith("!")){
41 | val q = code.replace("식", "").replace("!", "")
42 | print("${q.toUmmInt()}")
43 | }
44 | else if(code.endsWith("ㅋ")){
45 | val q = code.replace("식", "").replace("ㅋ", "")
46 | if(q == ""){
47 | println()
48 | }
49 | else {
50 | val b = q.toUmmInt()
51 |
52 | print(convertUnicodeToString("\\u${b.toString(16).padStart(4 - b.toString(16).length, '0')}"))
53 | }
54 | }
55 | }
56 | else if(code.startsWith("동탄")){
57 | if(code.contains("?")){
58 | val cc = code.replace("동탄", "").split("?")
59 |
60 | val r = cc[0].toUmmInt()
61 |
62 | if(r == 0){
63 | parseLine(cc[1])
64 | }
65 | }
66 | }
67 | else if(code.startsWith("준")){
68 | if(code.replace("준", "") == ""){
69 | throw java.lang.RuntimeException("문법 오류: 점프할 줄 번호 미지정 (${pc + 2}번 줄)")
70 | }
71 | else {
72 | val lPC = code.replace("준", "")
73 |
74 | pc = lPC.toUmmInt() - 3
75 | }
76 | }
77 | else if(code.contains("엄")){
78 | val c = code.split("엄")
79 |
80 | memory.setSafe(c[0].countChar("어"), c[1].toUmmInt())
81 | }
82 | else {
83 | return
84 | }
85 | return
86 | }
87 |
88 | fun main(args: Array) {
89 | if(args.isEmpty()){
90 | throw IOException("어떻게 파일 이름이 없냐ㅋㅋ")
91 | }
92 | else if(!args[0].endsWith(".umm")){
93 | throw IOException("어떻게 ${args[0]}이 파일이름이냐ㅋㅋ")
94 | }
95 |
96 | val f = File(args[0])
97 | if(!f.canRead()) {
98 | throw IOException("파일을 읽을 수 없음")
99 | }
100 | else {
101 | var codes = f.readText().trim().replace("~", "\n").split("\n")
102 |
103 | if(codes[0] != "어떻게" && codes.last() != "이 사람이름이냐ㅋㅋ"){
104 | throw Exception("어떻게 이게 엄랭이냐ㅋㅋ")
105 | }
106 |
107 | codes = codes.subList(1, codes.size)
108 |
109 | while(true){
110 | if(codes[pc] != "이 사람이름이냐ㅋㅋ"){
111 | parseLine(codes[pc].trim())
112 | pc++
113 | }
114 | else break
115 | }
116 | }
117 |
118 | exitProcess(0)
119 | }
--------------------------------------------------------------------------------
/umjunsik-lang-kotlin/src/main/kotlin/com/alphagot/kumjunsiklang/ParseUtils.kt:
--------------------------------------------------------------------------------
1 | package com.alphagot.kumjunsiklang
2 |
3 | import java.util.*
4 |
5 | fun String.countChar(c: String): Int {
6 | var ret = 0
7 | this.toCharArray().forEach {
8 | if(it.toString() == c){
9 | ret++
10 | }
11 | }
12 | return ret
13 | }
14 |
15 | fun String.toUmmInt(): Int {
16 | return toUmmmInt(this)
17 | }
18 |
19 | fun toUmmmInt(a: String): Int {
20 | var n = 0
21 | if (a.contains(" ")) {
22 | val b = a.split(" ").map {
23 | toUmmmIntInternal(it)
24 | }
25 | n = b[0]
26 | b.subList(1, b.size).forEach {
27 | n *= it
28 | }
29 | }
30 | else {
31 | n = toUmmmIntInternal(a)
32 | }
33 | return n
34 | }
35 |
36 | fun toUmmmIntInternal(a: String): Int {
37 | var s = a
38 | var n = 0
39 |
40 | if(s.contains("식?")) {
41 | val answer = Scanner(System.`in`).nextInt()
42 | s = s.replace("식?", ".".repeat(answer))
43 | }
44 | if(s.contains("어")) n += memory.getSafe(s.countChar("어") - 1)
45 | if(s.contains(".")) n += s.countChar(".")
46 | if(s.contains(",")) n -= s.countChar(",")
47 | return n
48 | }
49 |
50 | fun String.toVarIndex(isLoad: Boolean = true): Int {
51 | if(this.split(" ").size > 1){
52 | val s = this.split(" ")
53 |
54 | val b = mutableListOf()
55 | s.forEach { b.add(it.countChar("어") - 1) }
56 |
57 | var r = 1
58 |
59 | b.forEach {
60 | r *= it
61 | }
62 |
63 | return r + if(isLoad) -1 else 0
64 | }
65 | else {
66 | return this.countChar("어") + if(isLoad) -1 else 0
67 | }
68 | }
69 |
70 | fun String.isVariable(): Boolean = this.startsWith("어") || this.endsWith("엄")
71 |
72 | fun convertUnicodeToString(unicodeString: String): String {
73 | var str: String = unicodeString.split(" ")[0]
74 | str = str.replace("\\", "")
75 | val arr = str.split("u").toTypedArray()
76 | var text = ""
77 | for (i in 1 until arr.size) {
78 | val hexVal = arr[i].toInt(16)
79 | text += hexVal.toChar()
80 | }
81 |
82 | return text
83 | }
84 |
--------------------------------------------------------------------------------
/umjunsik-lang-node/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
--------------------------------------------------------------------------------
/umjunsik-lang-node/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "umjunsik-lang-node",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "license": "UNLICENSED",
6 | "scripts": {
7 | "build": "tsc"
8 | },
9 | "devDependencies": {
10 | "@types/node": "^14.6.4",
11 | "@types/readline-sync": "^1.4.3"
12 | },
13 | "dependencies": {
14 | "readline-sync": "^1.4.10",
15 | "typescript": "^4.0.2"
16 | }
17 | }
--------------------------------------------------------------------------------
/umjunsik-lang-node/src/index.ts:
--------------------------------------------------------------------------------
1 | import {promises as fs} from 'fs'
2 | import readline from 'readline-sync'
3 |
4 | function stringify(unicode: number) {
5 | return String.fromCharCode(unicode)
6 | }
7 |
8 | async function run(code: string) {
9 | const statements = code.trim().split(code.includes('~') ? '~' : '\n').map(line => line.trim())
10 |
11 | if(statements[0] !== '어떻게' || !statements.slice(-1)[0].startsWith('이 사람이름이냐')) {
12 | throw new Error('Error: 어떻게 이 코드가 엄랭이냐ㅋㅋ')
13 | }
14 |
15 | const variables: number[] = []
16 | let pointer = 0
17 |
18 | const evaluate = async (x: string): Promise => {
19 | let n = 0
20 | if(x.includes(' ')) return (await Promise.all(x.split(' ').map(evaluate))).reduce((a, b) => a * b)
21 | if(x.includes('식?')) {
22 | const answer= readline.question();
23 | x = x.replace('식?', '.'.repeat(Number(answer)))
24 | }
25 | if(x.includes('어')) n += variables[x.split('어').length - 1]
26 | if(x.includes('.')) n += x.split('.').length - 1
27 | if(x.includes(',')) n -= x.split(',').length - 1
28 | return n
29 | }
30 |
31 | const execute = async (statement: string): Promise => {
32 | if (statement.includes('동탄') && statement.includes('?')) { // IF GOTO
33 | const condition = await evaluate(statement.substring(2, statement.lastIndexOf('?') + 1))
34 | if (condition === 0) {
35 | return execute(statement.substr(statement.lastIndexOf('?') + 1))
36 | }
37 | return
38 | }
39 |
40 | if(statement.includes('엄')) {
41 | const variablePointer = statement.split('엄')[0].split('어').length
42 | const setteeValue = await evaluate(statement.split('엄')[1])
43 | variables[variablePointer] = setteeValue
44 | }
45 |
46 | if (statement.includes('식') && statement[statement.length - 1] === '!') {
47 | process.stdout.write(String(await evaluate(statement.slice(1, -1))))
48 | }
49 |
50 | if (statement.includes('식') && statement[statement.length - 1] === 'ㅋ') {
51 | if (statement === '식ㅋ') process.stdout.write('\n')
52 | process.stdout.write(stringify(await evaluate(statement.slice(1, -1))))
53 | }
54 |
55 | if(statement.includes('준')) {
56 | pointer = await evaluate(statement.split('준')[1]) - 1
57 | }
58 |
59 | if (statement.indexOf('화이팅!') === 0) {
60 | return evaluate(statement.split('화이팅!')[1])
61 | }
62 | }
63 |
64 | while(!statements[pointer].startsWith('이 사람이름이냐')) {
65 | const statement = statements[pointer++]
66 | const evaluated = await execute(statement)
67 | if(evaluated) return evaluated
68 | }
69 | }
70 |
71 | async function bootstrap(path: string) {
72 | try {
73 | try {
74 | await fs.access(path)
75 | } catch(e) {
76 | throw new Error(`Error: ${path}가 어떻게 파일이름이냐ㅋㅋ`)
77 | }
78 |
79 | await run((await fs.readFile(path, 'utf-8')))
80 | } catch(e) {
81 | process.stderr.write(`${e.message}\n`)
82 | }
83 | }
84 |
85 | if(process.argv[2]) bootstrap(process.argv[2])
--------------------------------------------------------------------------------
/umjunsik-lang-node/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "commonjs",
5 | "outDir": "dist",
6 | "esModuleInterop": true
7 | },
8 | "include": [
9 | "src"
10 | ]
11 | }
--------------------------------------------------------------------------------
/umjunsik-lang-node/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@types/node@^14.6.4":
6 | version "14.10.1"
7 | resolved "https://registry.yarnpkg.com/@types/node/-/node-14.10.1.tgz#cc323bad8e8a533d4822f45ce4e5326f36e42177"
8 | integrity sha512-aYNbO+FZ/3KGeQCEkNhHFRIzBOUgc7QvcVNKXbfnhDkSfwUv91JsQQa10rDgKSTSLkXZ1UIyPe4FJJNVgw1xWQ==
9 |
10 | "@types/readline-sync@^1.4.3":
11 | version "1.4.3"
12 | resolved "https://registry.yarnpkg.com/@types/readline-sync/-/readline-sync-1.4.3.tgz#eac55a39d5a349912062c9e5216cd550c07fd9c8"
13 | integrity sha512-YP9NVli96E+qQLAF2db+VjnAUEeZcFVg4YnMgr8kpDUFwQBnj31rPLOVHmazbKQhaIkJ9cMHsZhpKdzUeL0KTg==
14 |
15 | readline-sync@^1.4.10:
16 | version "1.4.10"
17 | resolved "https://registry.yarnpkg.com/readline-sync/-/readline-sync-1.4.10.tgz#41df7fbb4b6312d673011594145705bf56d8873b"
18 | integrity sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==
19 |
20 | typescript@^4.0.2:
21 | version "4.0.2"
22 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.2.tgz#7ea7c88777c723c681e33bf7988be5d008d05ac2"
23 | integrity sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==
24 |
--------------------------------------------------------------------------------
/umjunsik-lang-python/__init__.py:
--------------------------------------------------------------------------------
1 | from .runtime import Umjunsik
--------------------------------------------------------------------------------
/umjunsik-lang-python/__main__.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from .runtime import Umjunsik
3 |
4 | def main():
5 | if len(sys.argv) != 2:
6 | print("Usage: umjunsik ")
7 | sys.exit(1)
8 |
9 | filename = sys.argv[1]
10 | with open(filename, "r", encoding="UTF-8") as file:
11 | code = file.read()
12 |
13 | interpreter = Umjunsik()
14 | interpreter.compile(code)
15 |
16 | if __name__ == "__main__":
17 | main()
--------------------------------------------------------------------------------
/umjunsik-lang-python/runtime.py:
--------------------------------------------------------------------------------
1 | import sys
2 |
3 |
4 | class Umjunsik:
5 | def __init__(self):
6 | self.data = [0]*256
7 |
8 | def toNumber(self, code):
9 | tokens = code.split(' ')
10 | result = 1
11 | for token in tokens:
12 | num = (self.data[token.count('어') - 1] if token.count('어') else 0) + token.count('.') - token.count(',')
13 | result *= num
14 | return result
15 |
16 | @staticmethod
17 | def type(code):
18 | if '동탄' in code:
19 | return 'IF'
20 | if '준' in code:
21 | return 'MOVE'
22 | if '화이팅!' in code:
23 | return 'END'
24 | if '식' in code and '?' in code:
25 | return 'INPUT'
26 | if '식' in code and '!' in code:
27 | return 'PRINT'
28 | if '식' in code and 'ㅋ' in code:
29 | return 'PRINTASCII'
30 | if '엄' in code:
31 | return 'DEF'
32 |
33 | def compileLine(self, code):
34 | if code == '':
35 | return None
36 | TYPE = self.type(code)
37 |
38 | if TYPE == 'DEF':
39 | var, cmd = code.split('엄')
40 | self.data[var.count('어')] = self.toNumber(cmd)
41 | elif TYPE == 'END':
42 | print(self.toNumber(code.split('화이팅!')[1]), end='')
43 | sys.exit()
44 | elif TYPE == 'INPUT':
45 | self.data[code.replace('식?', '').count('어')] = int(input())
46 | elif TYPE == 'PRINT':
47 | print(self.toNumber(code[1:-1]), end='')
48 | elif TYPE == 'PRINTASCII':
49 | value = self.toNumber(code[1:-1])
50 | print(chr(value) if value else '\n', end='')
51 | elif TYPE == 'IF':
52 | cond, cmd = code.replace('동탄', '').split('?')
53 | if self.toNumber(cond) == 0:
54 | return cmd
55 | elif TYPE == 'MOVE':
56 | return self.toNumber(code.replace('준', ''))
57 |
58 | def compile(self, code, check=True, errors=100000):
59 | jun = False
60 | recode = ''
61 | spliter = '\n' if '\n' in code else '~'
62 | code = code.rstrip().split(spliter)
63 | if check and (code[0].replace(" ","") != '어떻게' or code[-1] != '이 사람이름이냐ㅋㅋ' or not code[0].startswith('어떻게')):
64 | raise SyntaxError('어떻게 이게 엄랭이냐!')
65 | index = 0
66 | error = 0
67 | while index < len(code):
68 | errorline = index
69 | c = code[index].strip()
70 | res = self.compileLine(c)
71 | if jun:
72 | jun = False
73 | code[index] = recode
74 | if isinstance(res, int):
75 | index = res-2
76 | if isinstance(res, str):
77 | recode = code[index]
78 | code[index] = res
79 | index -= 1
80 | jun = True
81 |
82 | index += 1
83 | error += 1
84 | if error == errors:
85 | raise RecursionError(str(errorline+1) + '번째 줄에서 무한 루프가 감지되었습니다.')
86 |
87 | def compilePath(self, path):
88 | with open(path) as file:
89 | code = ''.join(file.readlines())
90 | self.compile(code)
--------------------------------------------------------------------------------
/umjunsik-lang-rust/.gitignore:
--------------------------------------------------------------------------------
1 | /Cargo.lock
2 | /target
3 |
--------------------------------------------------------------------------------
/umjunsik-lang-rust/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 | members = ["lib", "interpreter", "compiler"]
3 |
--------------------------------------------------------------------------------
/umjunsik-lang-rust/README.md:
--------------------------------------------------------------------------------
1 | # umjunsik-lang-rust
2 |
3 | 엄랭의 Rust 구현체입니다. 현재 파서(umjunsik, `/lib`)와 인터프리터(rummi, `/interpreter`),
4 | 컴파일러(rummc, `/compiler`)가 개발되어 있습니다.
5 |
6 | ## 인터프리터
7 |
8 | `cargo run -p rummi`로 REPL을, `cargo run -p rummi -- <파일명>`으로 코드 파일을 실행할 수 있습니다.
9 |
10 | ## 컴파일러
11 |
12 | `cargo run -p rummc -- <파일명> -o <출력 파일명>`로 object 파일을 생성할 수 있습니다.
13 |
14 | 이후 `gcc -o <실행 파일명>