Skip to content

Commit

Permalink
Merge pull request #74 from rycont/implement-statement-rule
Browse files Browse the repository at this point in the history
feat: RULE_FLAGS.IS_STATEMENT
  • Loading branch information
rycont authored Jan 24, 2025
2 parents 6f3bf90 + 7e0aa09 commit 9a01d23
Show file tree
Hide file tree
Showing 16 changed files with 120 additions and 64 deletions.
2 changes: 1 addition & 1 deletion core/deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
},
"name": "@dalbit-yaksok/core",
"exports": "./mod.ts",
"version": "0.2.0-RC.6"
"version": "0.2.0-RC.7"
}
3 changes: 1 addition & 2 deletions core/prepare/parse/dynamicRule/functions/invoke-rule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import type {
FunctionTemplate,
FunctionTemplatePiece,
} from '../../../../type/function-template.ts'
import type { PatternUnit } from '../../rule.ts'
import type { Rule } from '../../rule.ts'
import type { Rule, PatternUnit } from '../../type.ts'

interface VariantedPart {
index: number
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { getTokensFromNodes } from '../../../../util/merge-tokens.ts'
import { Mention, MentionScope } from '../../../../node/mention.ts'
import { FunctionInvoke } from '../../../../node/function.ts'
import { Identifier, Node } from '../../../../node/base.ts'
import { Rule } from '../../rule.ts'
import { Token } from '../../../tokenize/token.ts'
import { getTokensFromNodes } from '../../../../util/merge-tokens.ts'

import type { Rule } from '../../type.ts'

export function createMentioningRule(
fileName: string,
Expand Down
7 changes: 4 additions & 3 deletions core/prepare/parse/dynamicRule/mention/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { getMentioningFiles } from './mentioning-files.ts'
import { getExportedRules } from './get-exported-rules.ts'

import type { CodeFile } from '../../../../type/code-file.ts'
import { FileForRunNotExistError } from '../../../../error/prepare.ts'
import { ErrorInModuleError } from '../../../../error/mention.ts'
import { TOKEN_TYPE } from '../../../tokenize/token.ts'
import { Rule } from '../../rule.ts'
import { FileForRunNotExistError } from '../../../../error/prepare.ts'

import type { CodeFile } from '../../../../type/code-file.ts'
import type { Rule } from '../../type.ts'

export function getRulesFromMentioningFile(codeFile: CodeFile): Rule[] {
if (!codeFile.mounted) {
Expand Down
2 changes: 1 addition & 1 deletion core/prepare/parse/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { parseIndent } from './parse-indent.ts'
import { Block } from '../../node/block.ts'

import type { CodeFile } from '../../type/code-file.ts'
import type { Rule } from './rule.ts'
import type { Rule } from './type.ts'
import { getTokensFromNodes } from '../../util/merge-tokens.ts'
import { YaksokError } from '../../error/common.ts'

Expand Down
1 change: 1 addition & 0 deletions core/prepare/parse/parse-indent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export function parseIndent(_tokens: Node[], indent = 0) {
const childTokens = getTokensFromNodes(child)

groups.push(new Block(child, childTokens))
groups.push(new EOL([]))
} else {
groups.push(token)
}
Expand Down
47 changes: 25 additions & 22 deletions core/prepare/parse/rule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import {
Loop,
MinusOperator,
MultiplyOperator,
type Node,
Operator,
PlusOperator,
Print,
Expand All @@ -40,22 +39,7 @@ import {
import { ListLoop } from '../../node/listLoop.ts'
import { IndexedValue } from '../../value/indexed.ts'
import { NumberValue, StringValue } from '../../value/primitive.ts'

import type { Token } from '../tokenize/token.ts'

export interface PatternUnit {
type: {
new (...args: any[]): Node
}
value?: string
as?: string
}

export type Rule = {
pattern: PatternUnit[]
factory: (nodes: Node[], tokens: Token[]) => Node
config?: Record<string, unknown>
}
import { Rule, RULE_FLAGS } from './type.ts'

export const BASIC_RULES: Rule[][] = [
[
Expand Down Expand Up @@ -344,6 +328,7 @@ export const BASIC_RULES: Rule[][] = [
tokens,
)
},
flags: [RULE_FLAGS.IS_STATEMENT],
},
{
pattern: [
Expand Down Expand Up @@ -391,6 +376,7 @@ export const BASIC_RULES: Rule[][] = [
tokens,
)
},
flags: [RULE_FLAGS.IS_STATEMENT],
},
],
]
Expand Down Expand Up @@ -468,6 +454,7 @@ export const ADVANCED_RULES: Rule[] = [

return new SetToIndex(target, value, tokens)
},
flags: [RULE_FLAGS.IS_STATEMENT],
},
{
pattern: [
Expand All @@ -481,29 +468,31 @@ export const ADVANCED_RULES: Rule[] = [
{
type: Evaluable,
},
{
type: EOL,
},
],
factory: (nodes, tokens) => {
const name = (nodes[0] as Identifier).value
const value = nodes[2] as Evaluable

return new SetVariable(name, value, tokens)
},
flags: [RULE_FLAGS.IS_STATEMENT],
},
{
pattern: [
{
type: IfStatement,
},
{
type: EOL,
},
{
type: ElseIfStatement,
},
],
factory: (nodes, tokens) => {
const [ifStatement, elseIfStatement] = nodes as [
const [ifStatement, _, elseIfStatement] = nodes as [
IfStatement,
EOL,
ElseIfStatement,
]

Expand All @@ -514,19 +503,24 @@ export const ADVANCED_RULES: Rule[] = [

return ifStatement
},
flags: [RULE_FLAGS.IS_STATEMENT],
},
{
pattern: [
{
type: IfStatement,
},
{
type: EOL,
},
{
type: ElseStatement,
},
],
factory: (nodes, tokens) => {
const [ifStatement, elseStatement] = nodes as [
const [ifStatement, _, elseStatement] = nodes as [
IfStatement,
EOL,
ElseStatement,
]

Expand All @@ -539,6 +533,7 @@ export const ADVANCED_RULES: Rule[] = [

return ifStatement
},
flags: [RULE_FLAGS.IS_STATEMENT],
},
{
pattern: [
Expand Down Expand Up @@ -570,6 +565,7 @@ export const ADVANCED_RULES: Rule[] = [

return new ElseIfStatement({ condition, body }, tokens)
},
flags: [RULE_FLAGS.IS_STATEMENT],
},
{
pattern: [
Expand All @@ -589,6 +585,7 @@ export const ADVANCED_RULES: Rule[] = [

return new ElseStatement(body, tokens)
},
flags: [RULE_FLAGS.IS_STATEMENT],
},
{
pattern: [
Expand Down Expand Up @@ -616,6 +613,7 @@ export const ADVANCED_RULES: Rule[] = [

return new IfStatement([{ condition, body }], tokens)
},
flags: [RULE_FLAGS.IS_STATEMENT],
},
{
pattern: [
Expand All @@ -631,6 +629,7 @@ export const ADVANCED_RULES: Rule[] = [
const value = nodes[0] as Evaluable
return new Print(value, tokens)
},
flags: [RULE_FLAGS.IS_STATEMENT],
},
{
pattern: [
Expand All @@ -646,6 +645,7 @@ export const ADVANCED_RULES: Rule[] = [
},
],
factory: (nodes, tokens) => new Loop(nodes[2] as Block, tokens),
flags: [RULE_FLAGS.IS_STATEMENT],
},
{
pattern: [
Expand All @@ -659,6 +659,7 @@ export const ADVANCED_RULES: Rule[] = [
},
],
factory: (_nodes, tokens) => new Break(tokens),
flags: [RULE_FLAGS.IS_STATEMENT],
},
{
pattern: [
Expand All @@ -672,6 +673,7 @@ export const ADVANCED_RULES: Rule[] = [
},
],
factory: (_nodes, tokens) => new Return(tokens),
flags: [RULE_FLAGS.IS_STATEMENT],
},
{
pattern: [
Expand Down Expand Up @@ -707,5 +709,6 @@ export const ADVANCED_RULES: Rule[] = [

return new ListLoop(list, name, body, tokens)
},
flags: [RULE_FLAGS.IS_STATEMENT],
},
]
2 changes: 1 addition & 1 deletion core/prepare/parse/satisfiesPattern.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { PatternUnit } from './rule.ts'
import type { Node } from '../../node/index.ts'
import type { PatternUnit } from './type.ts'

export function satisfiesPattern(tokens: Node[], pattern: PatternUnit[]) {
return pattern.every((pattern, index) => {
Expand Down
51 changes: 26 additions & 25 deletions core/prepare/parse/srParse.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,53 @@
import { type Rule, ADVANCED_RULES, BASIC_RULES } from './rule.ts'
import { ADVANCED_RULES, BASIC_RULES } from './rule.ts'
import { satisfiesPattern } from './satisfiesPattern.ts'

import { Block } from '../../node/block.ts'
import { TOKEN_TYPE } from '../tokenize/token.ts'
import { EOL } from '../../node/misc.ts'

import type { Node } from '../../node/base.ts'
import { getTokensFromNodes } from '../../util/merge-tokens.ts'
import { Rule, RULE_FLAGS } from './type.ts'
import { EOL } from '../../node/misc.ts'

export function SRParse(_tokens: Node[], rules: Rule[]) {
const tokens = [..._tokens]
const stack: Node[] = []
export function SRParse(_nodes: Node[], rules: Rule[]) {
const leftNodes = [..._nodes]
const buffer: Node[] = []

let changed = false

tokenloop: while (true) {
nodeloop: while (true) {
for (const rule of rules) {
if (stack.length < rule.pattern.length) continue
if (buffer.length < rule.pattern.length) continue

const stackSlice = stack.slice(-rule.pattern.length)
const stackSlice = buffer.slice(-rule.pattern.length)
const satisfies = satisfiesPattern(stackSlice, rule.pattern)

if (!satisfies) continue

const isStatement = rule.flags?.includes(RULE_FLAGS.IS_STATEMENT)

if (isStatement) {
const nextNode = leftNodes[0]
if (nextNode && !(nextNode instanceof EOL)) continue

const lastNode = buffer[buffer.length - rule.pattern.length - 1]
if (lastNode && !(lastNode instanceof EOL)) continue
}

const reduced = reduce(stackSlice, rule)

stack.splice(-rule.pattern.length, rule.pattern.length, reduced)
buffer.splice(-rule.pattern.length, rule.pattern.length, reduced)

changed = true
continue tokenloop
continue nodeloop
}

if (tokens.length === 0) break
stack.push(tokens.shift()!)
if (leftNodes.length === 0) break
buffer.push(leftNodes.shift()!)
}

return {
changed,
tokens: stack,
nodes: buffer,
}
}

Expand Down Expand Up @@ -66,22 +77,12 @@ export function callParseRecursively(
}
}

parsedTokens.push(
new EOL([
{
position: { column: 0, line: 0 },
value: '\n',
type: TOKEN_TYPE.NEW_LINE,
},
]),
)

const patternsByLevel = [...BASIC_RULES, externalPatterns, ADVANCED_RULES]

loop1: while (true) {
for (const patterns of patternsByLevel) {
const result = SRParse(parsedTokens, patterns)
parsedTokens = result.tokens
parsedTokens = result.nodes

if (result.changed) continue loop1
}
Expand Down
22 changes: 22 additions & 0 deletions core/prepare/parse/type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { Node } from '../../node/base.ts'
import type { Token } from '../tokenize/token.ts'

export interface PatternUnit {
type: {
new (...args: any[]): Node
}
value?: string
as?: string
}

export type Rule = {
pattern: PatternUnit[]
factory: (nodes: Node[], tokens: Token[]) => Node
config?: Record<string, unknown>
flags?: RULE_FLAGS[]
}

export enum RULE_FLAGS {
IS_STATEMENT,
DEBUG,
}
2 changes: 1 addition & 1 deletion core/type/code-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { parse } from '../prepare/parse/index.ts'
import { YaksokError } from '../error/common.ts'

import type { Token } from '../prepare/tokenize/token.ts'
import type { Rule } from '../prepare/parse/rule.ts'
import type { Rule } from '../prepare/parse/type.ts'
import type { Runtime } from '../runtime/index.ts'
import type { Block } from '../node/block.ts'

Expand Down
2 changes: 1 addition & 1 deletion deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"test",
"monaco-language-provider"
],
"version": "0.2.0-RC.6",
"version": "0.2.0-RC.7",
"tasks": {
"apply-version": "deno run --allow-read --allow-write apply-version.ts",
"publish": "deno task --recursive test && deno publish --allow-dirty"
Expand Down
Loading

0 comments on commit 9a01d23

Please sign in to comment.