Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zerobase Indexing, Equality Operator with Double Equal SIgn, Variable Assigning with Single Equal Sign #80

Merged
merged 14 commits into from
Mar 15, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/deno.json
Original file line number Diff line number Diff line change
@@ -6,5 +6,5 @@
},
"name": "@dalbit-yaksok/core",
"exports": "./mod.ts",
"version": "0.2.1"
"version": "0.3.0-nightly+20250315"
}
4 changes: 2 additions & 2 deletions core/error/indexed.ts
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@ export class NotEnumerableValueForListLoopError extends YaksokError {
)}는 목록 반복문에서 사용할 수 없어요. 목록 반복문에서는 목록을 사용해야 해요.`
}
}
export class ListIndexMustBeGreaterThan1Error extends YaksokError {
export class ListIndexMustBeGreaterOrEqualThan0Error extends YaksokError {
constructor(props: {
position?: Position

@@ -40,7 +40,7 @@ export class ListIndexMustBeGreaterThan1Error extends YaksokError {
}
}) {
super(props)
this.message = `목록의 인덱스는 1보다 크거나 같아야 해요. ${props.resource.index}는 그렇지 않아요.`
this.message = `목록의 인덱스는 0보다 크거나 같아야 해요. ${props.resource.index}는 그렇지 않아요.`
}
}

10 changes: 10 additions & 0 deletions core/error/unknown-node.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Token } from '../prepare/tokenize/token.ts'
import { YaksokError } from './common.ts'

export class UnknownNodeError extends YaksokError {
constructor(props: { tokens: Token[] }) {
super(props)

this.message = '올바르지 않은 코드에요. 문법을 다시 확인해주세요.'
}
}
15 changes: 15 additions & 0 deletions core/node/base.ts
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ import { NotDefinedIdentifierError } from '../error/variable.ts'
import type { Token } from '../prepare/tokenize/token.ts'
import type { ValueType } from '../value/base.ts'
import type { Scope } from '../executer/scope.ts'
import { UnknownNodeError } from '../error/unknown-node.ts'

export class Node {
[key: string]: unknown
@@ -115,3 +116,17 @@ export class Expression extends Node {
return this.value
}
}

export class UnknownNode extends Executable {
static override friendlyName = '알 수 없는 노드'

constructor(public value: string, public override tokens: Token[]) {
super()
}

override execute(): Promise<never> {
throw new UnknownNodeError({
tokens: this.tokens,
})
}
}
4 changes: 2 additions & 2 deletions core/node/operator.ts
Original file line number Diff line number Diff line change
@@ -227,14 +227,14 @@ export class IntegerDivideOperator extends Operator {
}

export class EqualOperator extends Operator {
static override friendlyName = '같다(=)'
static override friendlyName = '같다(==)'

constructor(public override tokens: Token[]) {
super(null, tokens)
}

override toPrint(): string {
return '='
return '=='
}

override call(...operands: ValueType[]): BooleanValue {
13 changes: 10 additions & 3 deletions core/prepare/lex/convert-tokens-to-nodes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { Expression, Identifier, Node, Operator } from '../../node/base.ts'
import {
Expression,
Identifier,
Node,
Operator,
UnknownNode,
} from '../../node/base.ts'
import { FFIBody } from '../../node/ffi.ts'
import { Mention } from '../../node/mention.ts'
import { Indent, EOL } from '../../node/misc.ts'
@@ -13,14 +19,13 @@ function mapTokenToNode(token: Token) {
switch (token.type) {
case TOKEN_TYPE.SPACE:
case TOKEN_TYPE.LINE_COMMENT:
case TOKEN_TYPE.UNKNOWN:
return null
case TOKEN_TYPE.COMMA:
case TOKEN_TYPE.OPENING_PARENTHESIS:
case TOKEN_TYPE.CLOSING_PARENTHESIS:
case TOKEN_TYPE.OPENING_BRACKET:
case TOKEN_TYPE.CLOSING_BRACKET:
case TOKEN_TYPE.COLON:
case TOKEN_TYPE.ASSIGNMENT:
return new Expression(token.value, [token])
case TOKEN_TYPE.NUMBER:
return new NumberLiteral(parseFloat(token.value), [token])
@@ -38,5 +43,7 @@ function mapTokenToNode(token: Token) {
return new EOL([token])
case TOKEN_TYPE.MENTION:
return new Mention(token.value.slice(1), [token])
case TOKEN_TYPE.UNKNOWN:
return new UnknownNode(token.value, [token])
}
}
6 changes: 3 additions & 3 deletions core/prepare/parse/rule.ts
Original file line number Diff line number Diff line change
@@ -138,7 +138,7 @@ export const BASIC_RULES: Rule[][] = [
pattern: [
{
type: Operator,
value: '=',
value: '==',
},
],
factory: (_nodes, tokens) => new EqualOperator(tokens),
@@ -351,7 +351,7 @@ export const ADVANCED_RULES: Rule[] = [
},
{
type: Expression,
value: ':',
value: '=',
},
{
type: Evaluable,
@@ -372,7 +372,7 @@ export const ADVANCED_RULES: Rule[] = [
},
{
type: Expression,
value: ':',
value: '=',
},
{
type: Evaluable,
66 changes: 47 additions & 19 deletions core/prepare/tokenize/rules.ts
Original file line number Diff line number Diff line change
@@ -8,14 +8,14 @@ const OPERATORS = [
'*',
'/',
'>',
'=',
'<',
'~',
'%',
'**',
'//',
'<=',
'>=',
'==',
]

const IDENTIFIER_STARTER_REGEX = /[a-zA-Z_가-힣ㄱ-ㅎ]/
@@ -155,28 +155,64 @@ export const RULES: {
return code
},
},
{
type: TOKEN_TYPE.ASSIGNMENT,
starter: ['='],
parse: (view, shift) => {
shift()

if (view() == '=') {
throw new NotAcceptableSignal()
}

return '='
},
},
{
type: TOKEN_TYPE.OPERATOR,
starter: OPERATORS.map((o) => o[0]),
parse: (_view, shift) => {
parse: (view, shift) => {
let value = shift()!

while (true) {
const appliable = getAppliableOperators(value)
const currentlyAppliable = getAppliableOperators(value)
if (!currentlyAppliable.length) {
break
}

const hasMatched = OPERATORS.includes(value)
const isOnlyPossibility =
hasMatched &&
getAppliableOperators(value + _view()).length === 0
const exactlyMatched = currentlyAppliable.includes(value)
const appliableWithNext = getAppliableOperators(value + view()!)

if (isOnlyPossibility) {
if (exactlyMatched && appliableWithNext.length === 0) {
break
}

if (appliable.length > 1) {
value += shift()!
continue
if (!appliableWithNext.length) {
throw new NotAcceptableSignal()
}

value += shift()!

// const hasMatched = OPERATORS.includes(value)
// const MatchWithNext =
// getAppliableOperators(value + _view()).length === 0

// const isOnlyPossibility = hasMatched && MatchWithNext
// const notPossible = !hasMatched && MatchWithNext

// if (notPossible) {
// throw new NotAcceptableSignal()
// }

// if (isOnlyPossibility) {
// break
// }

// if (!MatchWithNext) {
// value += shift()!
// continue
// }
// console.log('?')
}

return value
@@ -261,14 +297,6 @@ export const RULES: {
return value
},
},
{
type: TOKEN_TYPE.COLON,
starter: [':'],
parse: (_, shift) => {
shift()
return ':'
},
},
{
type: TOKEN_TYPE.LINE_COMMENT,
starter: ['#'],
4 changes: 2 additions & 2 deletions core/prepare/tokenize/token.ts
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ export enum TOKEN_TYPE {
NUMBER = 'NUMBER',
STRING = 'STRING',
OPERATOR = 'OPERATOR',
ASSIGNMENT = 'ASSIGNMENT',
SPACE = 'SPACE',
INDENT = 'INDENT',
IDENTIFIER = 'IDENTIFIER',
@@ -14,7 +15,6 @@ export enum TOKEN_TYPE {
CLOSING_BRACKET = 'CLOSING_BRACKET',
FFI_BODY = 'FFI_BODY',
NEW_LINE = 'NEW_LINE',
COLON = 'COLON',
LINE_COMMENT = 'LINE_COMMENT',
MENTION = 'MENTION',
UNKNOWN = 'UNKNOWN',
@@ -40,8 +40,8 @@ export const TOKEN_TYPE_TO_TEXT: Record<TOKEN_TYPE, string> = {
[TOKEN_TYPE.CLOSING_BRACKET]: '닫는 대괄호',
[TOKEN_TYPE.FFI_BODY]: '번역 코드',
[TOKEN_TYPE.NEW_LINE]: '줄바꿈',
[TOKEN_TYPE.COLON]: '쌍점',
[TOKEN_TYPE.LINE_COMMENT]: '주석',
[TOKEN_TYPE.MENTION]: '불러오기',
[TOKEN_TYPE.UNKNOWN]: '알 수 없음',
[TOKEN_TYPE.ASSIGNMENT]: '값 정하기',
}
8 changes: 4 additions & 4 deletions core/value/list.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {
ListIndexMustBeGreaterOrEqualThan0Error,
ListIndexTypeError,
ListIndexMustBeGreaterThan1Error,
} from '../error/indexed.ts'
import { ValueType } from './base.ts'
import { IndexedValue } from './indexed.ts'
@@ -12,7 +12,7 @@ export class ListValue extends IndexedValue {

constructor(entries: ValueType[]) {
const entriesMap = new Map(
entries.map((entry, index) => [index + 1, entry]),
entries.map((entry, index) => [index, entry]),
)

super(entriesMap)
@@ -40,13 +40,13 @@ export class ListValue extends IndexedValue {
})
}

const isProperIndex = index >= 1
const isProperIndex = index >= 0

if (isProperIndex) {
return
}

throw new ListIndexMustBeGreaterThan1Error({
throw new ListIndexMustBeGreaterOrEqualThan0Error({
resource: {
index,
},
4 changes: 2 additions & 2 deletions deno.json
Original file line number Diff line number Diff line change
@@ -22,9 +22,9 @@
"test",
"monaco-language-provider"
],
"version": "0.2.1",
"version": "1.0.0-nightly+20250315",
"tasks": {
"apply-version": "deno run --allow-read --allow-write apply-version.ts",
"publish": "deno task --recursive test && deno publish --allow-dirty"
}
}
}
4 changes: 2 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -35,9 +35,9 @@ features:
<script setup>

const DEFAULT_CODE = `약속, 키가 (키)cm이고 몸무게가 (몸무게)일 때 비만도
결과: 몸무게 / (키 / 100 * 키 / 100)
결과 = 몸무게 / (키 / 100 * 키 / 100)

비만도: 키가 (170)cm이고 몸무게가 (70)일 때 비만도
비만도 = 키가 (170)cm이고 몸무게가 (70)일 때 비만도

비만도 보여주기
비만도 보여줄까말까
10 changes: 5 additions & 5 deletions docs/language/10. 약속 (함수).md
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@
약속을 정의할 때는 `약속` 키워드로 시작하며, 다음과 같은 형식으로 만듭니다:

<code-runner :code='`약속, 반지름이 (반지름)인 원의 넓이
결과: 반지름 * 반지름 * 3.14\n
결과 = 반지름 * 반지름 * 3.14\n
반지름이 (5)인 원의 넓이 보여주기`' />

위 예제에서는 반지름으로 원의 넓이를 계산하는 약속을 만들었습니다. 약속을 만들 때는:
@@ -30,8 +30,8 @@
약속은 여러 개의 매개변수를 가질 수 있습니다.

<code-runner :code='`약속, (숫자1)와 (숫자2)의 합
결과: 숫자1 + 숫자2\n
합계: (5)와 (3)의 합
결과 = 숫자1 + 숫자2\n
합계 = (5)와 (3)의 합
합계 보여주기`' />

## 고급: 한국어의 조사 변형 반영하기
@@ -68,8 +68,8 @@
<code-runner :challenge='{
output: "77",
answerCode: `약속, 섭씨 (온도)도를 화씨로 바꾸기
결과: 온도 * 9/5 + 32\n
화씨: 섭씨 (25)도를 화씨로 바꾸기
결과 = 온도 * 9/5 + 32\n
화씨 = 섭씨 (25)도를 화씨로 바꾸기
화씨 보여주기`
}'
/>
4 changes: 2 additions & 2 deletions docs/language/11. 고급: 불러오기.md
Original file line number Diff line number Diff line change
@@ -35,8 +35,8 @@
**차종**이라는 파일에서 다음과 같은 변수를 제공한다고 가정합니다.

```Vyper
KTX이음: "KTX-이음"
무궁화호: "무궁화호"
KTX이음 = "KTX-이음"
무궁화호 = "무궁화호"
```

그렇다면 다음과 같이 사용할 수 있습니다.
Loading