T-T
This commit is contained in:
parent
6817734ed9
commit
99c294a9ba
14 changed files with 19528 additions and 19413 deletions
|
|
@ -1,3 +1,49 @@
|
|||
import { Class } from "../components/Class.js"
|
||||
import { UI } from "../components/UI.js"
|
||||
import { Renderer } from "../types/enums/Renderer.js"
|
||||
import { Type } from "../types/enums/Type.js"
|
||||
|
||||
export class Memory extends Class {}
|
||||
type Element = UI<Type, Renderer | null>
|
||||
interface FileInterface {
|
||||
namespace: string
|
||||
elements: Element[]
|
||||
}
|
||||
type Files = Map<string, FileInterface>
|
||||
|
||||
export class Memory extends Class {
|
||||
protected static files: Files = new Map<string, FileInterface>()
|
||||
|
||||
public static add(element: UI<Type, Renderer | null>) {
|
||||
let file = Memory.files.get(element.path)
|
||||
|
||||
if (!file) {
|
||||
file = { namespace: element.namespace, elements: [] }
|
||||
Memory.files.set(element.path, file)
|
||||
}
|
||||
|
||||
if (file.namespace === element.namespace) file.elements.push(element)
|
||||
else {
|
||||
console.error(`Namespace mismatch on ${element.name} (${element.namespace} !== ${file.namespace})`)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
public static build() {
|
||||
const data: Map<string, any> = new Map()
|
||||
|
||||
Memory.files.entries().forEach(([path, { elements, namespace }]) => {
|
||||
const record: Record<string, any> = {}
|
||||
|
||||
elements.forEach(element => {
|
||||
record[element.name] = element
|
||||
})
|
||||
|
||||
data.set(path, {
|
||||
namespace,
|
||||
...record,
|
||||
})
|
||||
})
|
||||
|
||||
return data
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { Memory } from "./Memory.js"
|
||||
|
||||
process.on("beforeExit", () => {})
|
||||
process.on("beforeExit", () => {
|
||||
// console.log(Memory.build())
|
||||
})
|
||||
|
|
|
|||
|
|
@ -42,93 +42,6 @@ export function Lexer(input: string, start: number = 0, end?: number) {
|
|||
break
|
||||
}
|
||||
|
||||
case "`": {
|
||||
const tsTokens: TSToken[] = []
|
||||
const start = index
|
||||
|
||||
const tokenization = (start: number) => {
|
||||
while (index < input.length) {
|
||||
const char = input[index]
|
||||
if (char === "`") {
|
||||
index++
|
||||
eatString()
|
||||
} else if (char === "}") {
|
||||
tsTokens.push({
|
||||
kind: TSTokenKind.EXPRESSION,
|
||||
tokens: Lexer(input, start + 1, index),
|
||||
})
|
||||
break
|
||||
}
|
||||
index++
|
||||
}
|
||||
}
|
||||
|
||||
const stringification = (start: number) => {
|
||||
while (index < input.length) {
|
||||
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, index - start + 1))
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
case ",":
|
||||
tokens.push(makeToken(input, TokenKind.COMMA, index))
|
||||
break
|
||||
|
|
@ -165,6 +78,92 @@ export function Lexer(input: string, start: number = 0, end?: number) {
|
|||
else tokens.push(makeToken(input, TokenKind.OPERATOR, index))
|
||||
break
|
||||
|
||||
case "f":
|
||||
case "F": {
|
||||
if (input[index + 1] === "'") {
|
||||
const tsTokens: TSToken[] = []
|
||||
const start = ++index
|
||||
|
||||
const tokenization = (start: number) => {
|
||||
while (index < input.length) {
|
||||
const char = input[index]
|
||||
if (char === "'") {
|
||||
index++
|
||||
eatString()
|
||||
} else if (char === "}") {
|
||||
tsTokens.push({
|
||||
kind: TSTokenKind.EXPRESSION,
|
||||
tokens: Lexer(input, start + 1, index),
|
||||
})
|
||||
break
|
||||
}
|
||||
index++
|
||||
}
|
||||
}
|
||||
|
||||
const stringification = (start: number) => {
|
||||
while (index < input.length) {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
default: {
|
||||
let start = index
|
||||
|
||||
|
|
@ -176,7 +175,7 @@ export function Lexer(input: string, start: number = 0, end?: number) {
|
|||
tokens.push(makeToken(input, TokenKind.WORD, start, index - start + 1))
|
||||
} else if (!Checker.isBlankChar(token)) {
|
||||
console.error(
|
||||
`\x1b[31m${input.slice(0, index)}>>>${token}<<<${input.slice(index + 1)}\nInvalid character.\x1b[0m`,
|
||||
`\x1b[31merror: ${input + "\n" + " ".repeat(index + 7) + "^"}\nInvalid character.\x1b[0m`,
|
||||
)
|
||||
throw new Error()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,10 @@ export class Parser {
|
|||
constructor(private input: string) {
|
||||
this.tokens = Lexer(this.input)
|
||||
this.output = this.parseExpression()
|
||||
|
||||
if (this.at()) {
|
||||
this.expect(TokenKind.EOF, "Unexpected token!")
|
||||
}
|
||||
}
|
||||
|
||||
at() {
|
||||
|
|
@ -247,7 +251,12 @@ export class Parser {
|
|||
)
|
||||
return <string>callerToken.value
|
||||
} else {
|
||||
this.expect(TokenKind.WORD, "Unexpected token!")
|
||||
if (callerToken.kind === TokenKind.WORD)
|
||||
this.warn(
|
||||
`Implicit string literal '${callerToken.value}'. Use quoted string ('${callerToken.value}') for clarity!`,
|
||||
callerToken,
|
||||
)
|
||||
else this.expect(TokenKind.WORD, "Unexpected token!")
|
||||
return <string>callerToken.value
|
||||
}
|
||||
}
|
||||
|
|
@ -274,14 +283,11 @@ export class Parser {
|
|||
|
||||
private warn(err: string, token?: Token) {
|
||||
const prev = token || this.at()
|
||||
console.warn(`\x1b[33m${this.getPointer(prev)}\n` + `[WARNING]: ${err}\x1b[0m`)
|
||||
console.warn(`\x1b[33mwarn:${this.getPointer(prev, true)}\n` + `[WARNING]: ${err}\x1b[0m`)
|
||||
}
|
||||
|
||||
private getPointer(token: Token) {
|
||||
return `${this.input.slice(0, token.start)}>>>${this.input.slice(
|
||||
token.start,
|
||||
token.start + token.length,
|
||||
)}<<<${this.input.slice(token.start + token.length)}`
|
||||
private getPointer(token: Token, isWarn = false) {
|
||||
return this.input + "\n" + " ".repeat(token.start + (isWarn ? 5 : 7)) + "^".repeat(token.length)
|
||||
}
|
||||
|
||||
out(): { gen?: BindingItem[]; out: Expression } {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ export enum TokenKind {
|
|||
|
||||
OPERATOR,
|
||||
COMMA,
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
export enum TSTokenKind {
|
||||
|
|
|
|||
Reference in a new issue