idk
This commit is contained in:
parent
99c294a9ba
commit
3719a3f6b3
6 changed files with 57 additions and 111 deletions
|
|
@ -1,13 +1,13 @@
|
||||||
import { Binding } from "../types/properties/value.js"
|
import { Binding } from "../types/properties/value.js"
|
||||||
|
|
||||||
export function FormatProperties(properties: any) {
|
export function FormatProperties(properties: any) {
|
||||||
const property_bags: Record<Binding, any> = {}
|
const property_bag: Record<Binding, any> = {}
|
||||||
|
|
||||||
for (const key in properties) {
|
for (const key in properties) {
|
||||||
const value = properties[key]
|
const value = properties[key]
|
||||||
|
|
||||||
if (key.startsWith("#")) {
|
if (key.startsWith("#")) {
|
||||||
property_bags[<Binding>key] = value
|
property_bag[<Binding>key] = value
|
||||||
delete properties[key]
|
delete properties[key]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -17,11 +17,11 @@ export function FormatProperties(properties: any) {
|
||||||
delete properties.anchor
|
delete properties.anchor
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Object.keys(property_bags).length) {
|
if (Object.keys(property_bag).length) {
|
||||||
if (properties.property_bags) {
|
if (properties.property_bag) {
|
||||||
properties.property_bags = { ...property_bags, ...properties.property_bags }
|
properties.property_bag = { ...property_bag, ...properties.property_bag }
|
||||||
} else {
|
} else {
|
||||||
properties.property_bags = property_bags
|
properties.property_bag = property_bag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
import { makeToken, TokenKind, Token, TSToken, TSTokenKind } from "./types.js"
|
import { makeToken, TokenKind, Token, TSToken, TSTokenKind } from "./types.js"
|
||||||
import * as Checker from "./Checker.js"
|
import * as Checker from "./Checker.js"
|
||||||
|
|
||||||
export function Lexer(input: string, start: number = 0, end?: number) {
|
export function Lexer(input: string, start: number = 0, length?: number) {
|
||||||
const tokens: Token[] = []
|
const tokens: Token[] = []
|
||||||
|
|
||||||
if (input.length === 0) return tokens
|
if (input.length === 0) return tokens
|
||||||
|
length ||= input.length
|
||||||
|
|
||||||
|
console.log(input.slice(start, length))
|
||||||
|
|
||||||
let index = start
|
let index = start
|
||||||
do {
|
do {
|
||||||
|
|
@ -17,11 +20,18 @@ export function Lexer(input: string, start: number = 0, end?: number) {
|
||||||
case "#":
|
case "#":
|
||||||
case "$": {
|
case "$": {
|
||||||
const start = index++
|
const start = index++
|
||||||
|
while (index < length) {
|
||||||
while (index < input.length) {
|
|
||||||
const token = input[index]
|
const token = input[index]
|
||||||
if (Checker.isWordChar(token)) index++
|
if (Checker.isWordChar(token)) index++
|
||||||
else break
|
else {
|
||||||
|
if (start + 1 === index) {
|
||||||
|
console.error(
|
||||||
|
`\x1b[31merror: ${input + "\n" + " ".repeat(index + 6) + "^"}\nInvalid character.\x1b[0m`,
|
||||||
|
)
|
||||||
|
throw new Error()
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tokens.push(makeToken(input, TokenKind.VARIABLE, start, index-- - start))
|
tokens.push(makeToken(input, TokenKind.VARIABLE, start, index-- - start))
|
||||||
|
|
@ -29,19 +39,6 @@ export function Lexer(input: string, start: number = 0, end?: number) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
case "'": {
|
|
||||||
const start = index++
|
|
||||||
|
|
||||||
do {
|
|
||||||
const token = input[index]
|
|
||||||
if (token === "'") break
|
|
||||||
} while (++index < input.length)
|
|
||||||
|
|
||||||
tokens.push(makeToken(input, TokenKind.STRING, start, index - start + 1))
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case ",":
|
case ",":
|
||||||
tokens.push(makeToken(input, TokenKind.COMMA, index))
|
tokens.push(makeToken(input, TokenKind.COMMA, index))
|
||||||
break
|
break
|
||||||
|
|
@ -78,88 +75,39 @@ export function Lexer(input: string, start: number = 0, end?: number) {
|
||||||
else tokens.push(makeToken(input, TokenKind.OPERATOR, index))
|
else tokens.push(makeToken(input, TokenKind.OPERATOR, index))
|
||||||
break
|
break
|
||||||
|
|
||||||
case "f":
|
// string
|
||||||
case "F": {
|
case "'": {
|
||||||
|
const start = index++
|
||||||
|
|
||||||
|
do {
|
||||||
|
const token = input[index]
|
||||||
|
if (token === "'") break
|
||||||
|
} while (++index < length)
|
||||||
|
|
||||||
|
tokens.push(makeToken(input, TokenKind.STRING, start, index - start + 1))
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// template string
|
||||||
|
case "f": {
|
||||||
if (input[index + 1] === "'") {
|
if (input[index + 1] === "'") {
|
||||||
const tsTokens: TSToken[] = []
|
const tsTokens: TSToken[] = []
|
||||||
const start = ++index
|
const start = index
|
||||||
|
|
||||||
const tokenization = (start: number) => {
|
const templateStringTokens = (start: number) => {
|
||||||
while (index < input.length) {
|
while (index < length) {
|
||||||
const char = input[index]
|
const char = input[index]
|
||||||
|
|
||||||
if (char === "'") {
|
if (char === "'") {
|
||||||
index++
|
|
||||||
eatString()
|
|
||||||
} else if (char === "}") {
|
|
||||||
tsTokens.push({
|
|
||||||
kind: TSTokenKind.EXPRESSION,
|
|
||||||
tokens: Lexer(input, start + 1, index),
|
|
||||||
})
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
|
||||||
index++
|
index++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const stringification = (start: number) => {
|
templateStringTokens(index)
|
||||||
while (index < input.length) {
|
tokens.push(makeToken(tsTokens, TokenKind.TEMPLATE_STRING, start, index - start))
|
||||||
const char = input[index]
|
|
||||||
if (char === "'") {
|
|
||||||
if (start + 1 !== index)
|
|
||||||
tsTokens.push({
|
|
||||||
kind: TSTokenKind.STRING,
|
|
||||||
tokens: {
|
|
||||||
kind: TokenKind.STRING,
|
|
||||||
start: start + 1,
|
|
||||||
length: index - start + 1,
|
|
||||||
value: `'${input.slice(start + 1, index)}'`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
break
|
|
||||||
} else if (char === "#" && input[index + 1] === "{") {
|
|
||||||
tsTokens.push({
|
|
||||||
kind: TSTokenKind.STRING,
|
|
||||||
tokens: {
|
|
||||||
value: `'${input.slice(start + 1, index)}'`,
|
|
||||||
kind: TokenKind.STRING,
|
|
||||||
length: index - start + 1,
|
|
||||||
start,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
tokenization(++index)
|
|
||||||
start = index
|
|
||||||
}
|
|
||||||
index++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const eatString = () => {
|
|
||||||
while (index < input.length) {
|
|
||||||
const char = input[index]
|
|
||||||
if (char === "'") {
|
|
||||||
break
|
|
||||||
} else if (char === "#" && input[index + 1] === "{") {
|
|
||||||
index++
|
|
||||||
eatTemplate()
|
|
||||||
}
|
|
||||||
index++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const eatTemplate = () => {
|
|
||||||
while (index < input.length) {
|
|
||||||
const char = input[index]
|
|
||||||
if (char === "'") {
|
|
||||||
eatString()
|
|
||||||
} else if (char === "}") {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
index++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stringification(index++)
|
|
||||||
tokens.push(makeToken(tsTokens, TokenKind.TEMPLATE_STRING, start - 1, index - start + 1))
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -181,7 +129,7 @@ export function Lexer(input: string, start: number = 0, end?: number) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (++index < (end || input.length))
|
} while (++index < length)
|
||||||
|
|
||||||
return tokens
|
return tokens
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -292,7 +292,7 @@ export class Parser {
|
||||||
|
|
||||||
out(): { gen?: BindingItem[]; out: Expression } {
|
out(): { gen?: BindingItem[]; out: Expression } {
|
||||||
return {
|
return {
|
||||||
out: this.output,
|
out: `(${this.output})`,
|
||||||
gen: this.genBindings.map(
|
gen: this.genBindings.map(
|
||||||
({ source, target }) =>
|
({ source, target }) =>
|
||||||
<BindingItem>{
|
<BindingItem>{
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ export enum TokenKind {
|
||||||
OPERATOR,
|
OPERATOR,
|
||||||
COMMA,
|
COMMA,
|
||||||
|
|
||||||
EOF
|
EOF,
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum TSTokenKind {
|
export enum TSTokenKind {
|
||||||
|
|
@ -55,9 +55,9 @@ export function makeToken<T extends TokenKind>(
|
||||||
length: number = 1,
|
length: number = 1,
|
||||||
): Token {
|
): Token {
|
||||||
if (kind === TokenKind.TEMPLATE_STRING) {
|
if (kind === TokenKind.TEMPLATE_STRING) {
|
||||||
return { value: input as TSToken[], kind: kind, start, length }
|
return { kind: kind, start, length, value: input as TSToken[] }
|
||||||
} else {
|
} else {
|
||||||
return { value: input.slice(start, start + length) as string, kind, start, length }
|
return { kind, start, length, value: input.slice(start, start + length) as string }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,3 +9,5 @@ export * from "./types/enums/index.js"
|
||||||
export * as Properties from "./types/properties/index.js"
|
export * as Properties from "./types/properties/index.js"
|
||||||
|
|
||||||
export { ItemAuxID } from "./types/enums/Items.js"
|
export { ItemAuxID } from "./types/enums/Items.js"
|
||||||
|
|
||||||
|
export * from "./compilers/bindings/index.js"
|
||||||
|
|
|
||||||
18
test/app.ts
18
test/app.ts
|
|
@ -1,14 +1,10 @@
|
||||||
import { BagBinding, f, ItemAuxID, Label } from ".."
|
import { Panel } from ".."
|
||||||
|
|
||||||
const text = Label({
|
const panel = Panel()
|
||||||
text: "#text",
|
|
||||||
[BagBinding.ITEM_ID_AUX]: ItemAuxID.DIAMOND,
|
panel.addBindings({
|
||||||
"#x": 2,
|
source_property_name: `[ $abc ]`,
|
||||||
|
target_property_name: "#text",
|
||||||
})
|
})
|
||||||
|
|
||||||
text.addBindings({
|
console.log(panel)
|
||||||
source_property_name: f(`Test: #{ -(${BagBinding.ITEM_ID_AUX} % #x) == 0 }`),
|
|
||||||
target_property_name: BagBinding.TEXT,
|
|
||||||
})
|
|
||||||
|
|
||||||
console.log(text)
|
|
||||||
|
|
|
||||||
Reference in a new issue