refactor: temporarily remove bitwise operations
This commit is contained in:
parent
635285b8d0
commit
3c0f9b31c6
9 changed files with 192 additions and 184 deletions
|
|
@ -4,7 +4,7 @@
|
|||
*/
|
||||
export const config = {
|
||||
packinfo: {
|
||||
name: "AsaJS - Installer Test",
|
||||
name: "AsaJS",
|
||||
description: "Create your Minecraft JSON-UI resource packs using JavaScript.",
|
||||
version: [4, 0, 1],
|
||||
},
|
||||
|
|
|
|||
47
src/compilers/bindings/Binary.ts
Normal file
47
src/compilers/bindings/Binary.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import { RandomBindingString } from "../../components/Utils.js"
|
||||
import { Binding } from "../../types/properties/value.js"
|
||||
import { defaultFunctions } from "./Function.js"
|
||||
import { GenBinding } from "./types.js"
|
||||
|
||||
export function intToBin(input: string) {
|
||||
const { abs, negabs } = defaultFunctions
|
||||
|
||||
const ret = RandomBindingString(16)
|
||||
const bindings: GenBinding[] = []
|
||||
|
||||
// negative bit
|
||||
bindings.push({
|
||||
source: `(${input} < 0)`,
|
||||
target: `${ret}0`,
|
||||
})
|
||||
|
||||
return {
|
||||
ret,
|
||||
bindings,
|
||||
}
|
||||
}
|
||||
|
||||
export function binToInt(input: Binding) {
|
||||
const ret = RandomBindingString(16)
|
||||
const bindings: GenBinding[] = []
|
||||
|
||||
const nevBind = (input + "0") as Binding
|
||||
|
||||
// Is reverse to positive
|
||||
bindings.push({
|
||||
source: `(-1 + ((${nevBind} = 0) * 2))`,
|
||||
target: `${ret}0`,
|
||||
})
|
||||
|
||||
bindings.push({
|
||||
source: `(${Array.from({ length: 31 }, ($, i) => {
|
||||
return `${input}${i + 1}`
|
||||
}).join(" + ")})`,
|
||||
target: ret,
|
||||
})
|
||||
|
||||
return {
|
||||
ret,
|
||||
bindings,
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { RandomBindingString } from "../../components/Utils.js"
|
||||
import { Parser } from "./Parser.js"
|
||||
import { intToBin } from "./Binary.js"
|
||||
import { Expression, GenBinding } from "./types.js"
|
||||
|
||||
type Callback = (...args: Expression[]) => {
|
||||
|
|
@ -13,82 +13,134 @@ function callFn(name: string, ...args: Expression[]) {
|
|||
return FunctionMap.get(name)!(...args)
|
||||
}
|
||||
|
||||
// Default Functions
|
||||
FunctionMap.set("abs", number => {
|
||||
const randomBinding = RandomBindingString(16)
|
||||
return {
|
||||
genBindings: [{ source: `((-1 + (${number} > 0) * 2) * ${number})`, target: randomBinding }],
|
||||
value: randomBinding,
|
||||
}
|
||||
})
|
||||
export const defaultFunctions = {
|
||||
/**
|
||||
* Returns the absolute value of a number (the value without regard to whether it is positive or negative). For example, the absolute value of -5 is the same as the absolute value of 5.
|
||||
* @param number
|
||||
* @returns
|
||||
*/
|
||||
abs: number => {
|
||||
const randomBinding = RandomBindingString(16)
|
||||
return {
|
||||
genBindings: [{ source: `((-1 + (${number} > 0) * 2) * ${number})`, target: randomBinding }],
|
||||
value: randomBinding,
|
||||
}
|
||||
},
|
||||
|
||||
FunctionMap.set("new", expression => {
|
||||
const randomBinding = RandomBindingString(16)
|
||||
return {
|
||||
genBindings: [{ source: expression, target: randomBinding }],
|
||||
value: randomBinding,
|
||||
}
|
||||
})
|
||||
/**
|
||||
* Returns the negative absolute value of a number (the value without regard to whether it is positive or negative). For example, the absolute value of 5 is the same as the negative absolute value of -5.
|
||||
* @param number
|
||||
* @returns
|
||||
*/
|
||||
negabs: number => {
|
||||
const randomBinding = RandomBindingString(16)
|
||||
return {
|
||||
genBindings: [{ source: `((-1 + (${number} < 0) * 2) * ${number})`, target: randomBinding }],
|
||||
value: randomBinding,
|
||||
}
|
||||
},
|
||||
|
||||
FunctionMap.set("sqrt", number => {
|
||||
const rtn = RandomBindingString(16),
|
||||
$1 = RandomBindingString(16),
|
||||
$2 = RandomBindingString(16)
|
||||
/**
|
||||
* Generate a new binding for expression
|
||||
* @param expression
|
||||
* @returns
|
||||
*/
|
||||
new: expression => {
|
||||
const randomBinding = RandomBindingString(16)
|
||||
return {
|
||||
genBindings: [{ source: expression, target: randomBinding }],
|
||||
value: randomBinding,
|
||||
}
|
||||
},
|
||||
|
||||
const { genBindings: absValue, value: absRtn } = callFn("abs", number)
|
||||
/**
|
||||
* Returns the square root of a number.
|
||||
* @param number
|
||||
* @returns
|
||||
*/
|
||||
sqrt: number => {
|
||||
const rtn = RandomBindingString(16),
|
||||
$1 = RandomBindingString(16),
|
||||
$2 = RandomBindingString(16)
|
||||
|
||||
return {
|
||||
genBindings: [
|
||||
{
|
||||
source: `${number} * 100 / 2`,
|
||||
target: $1,
|
||||
},
|
||||
...absValue!,
|
||||
{
|
||||
source: `${absRtn} > 1`,
|
||||
target: $2,
|
||||
},
|
||||
{
|
||||
source: `(${number} < 0) * -1 + (${number} > -1) * (${$2} * ((${rtn} + ${number} / ${rtn}) / 2) + (not ${$2}) * ${rtn})`,
|
||||
target: rtn,
|
||||
},
|
||||
],
|
||||
value: rtn,
|
||||
}
|
||||
})
|
||||
const { genBindings: absValue, value: absRtn } = callFn("abs", number)
|
||||
|
||||
FunctionMap.set("translatable", key => {
|
||||
return {
|
||||
value: `'%' + ${key}`,
|
||||
}
|
||||
})
|
||||
return {
|
||||
genBindings: [
|
||||
{
|
||||
source: `${number} * 100 / 2`,
|
||||
target: $1,
|
||||
},
|
||||
...absValue!,
|
||||
{
|
||||
source: `${absRtn} > 1`,
|
||||
target: $2,
|
||||
},
|
||||
{
|
||||
source: `(${number} < 0) * -1 + (${number} > -1) * (${$2} * ((${rtn} + ${number} / ${rtn}) / 2) + (not ${$2}) * ${rtn})`,
|
||||
target: rtn,
|
||||
},
|
||||
],
|
||||
value: rtn,
|
||||
}
|
||||
},
|
||||
|
||||
FunctionMap.set("bin", input => {
|
||||
const { ret, bindings } = Parser.intToBin(input)
|
||||
/**
|
||||
* Return a translatable string
|
||||
* @param key
|
||||
* @returns
|
||||
*/
|
||||
translatable: key => {
|
||||
return {
|
||||
value: `'%' + ${key}`,
|
||||
}
|
||||
},
|
||||
|
||||
bindings.push({
|
||||
source: `'§z' + ${Array.from({ length: 30 }, (_, i) => `${ret}${30 - i - 1}`).join(" + ")}`,
|
||||
target: ret,
|
||||
})
|
||||
/**
|
||||
* Return a binary of int32 number in string
|
||||
* @param value
|
||||
* @param bait
|
||||
* @returns
|
||||
*/
|
||||
// bin: value => {
|
||||
// const {} = intToBin(value)
|
||||
|
||||
return { genBindings: bindings, value: ret }
|
||||
})
|
||||
// return {
|
||||
// value,
|
||||
// }
|
||||
// },
|
||||
|
||||
FunctionMap.set("bind", (value, bait) => {
|
||||
const ret = RandomBindingString(16)
|
||||
/**
|
||||
* Generate value bindings
|
||||
* @param value
|
||||
* @param bait
|
||||
* @returns
|
||||
*/
|
||||
bind: (value, bait) => {
|
||||
const ret = RandomBindingString(16)
|
||||
|
||||
if (!bait) {
|
||||
throw new Error("Bait is required")
|
||||
}
|
||||
if (!bait) {
|
||||
throw new Error("Bait is required")
|
||||
}
|
||||
|
||||
return {
|
||||
genBindings: [{ source: `((${bait} - ${bait}) + ${value})`, target: ret }],
|
||||
value: ret,
|
||||
}
|
||||
})
|
||||
return {
|
||||
genBindings: [{ source: `((${bait} - ${bait}) + ${value})`, target: ret }],
|
||||
value: ret,
|
||||
}
|
||||
},
|
||||
|
||||
FunctionMap.set("int", input => {
|
||||
return {
|
||||
value: input,
|
||||
}
|
||||
})
|
||||
/**
|
||||
* Return a int of float number, because string in JSON-UI cannot read it.
|
||||
* @param input
|
||||
* @returns
|
||||
*/
|
||||
int: input => {
|
||||
const ret = RandomBindingString(16)
|
||||
return {
|
||||
genBindings: [{ source: `${input}`, target: ret }],
|
||||
value: ret,
|
||||
}
|
||||
},
|
||||
} satisfies Record<string, Callback>
|
||||
|
||||
Object.entries(defaultFunctions).forEach(([key, value]) => FunctionMap.set(key, value))
|
||||
|
|
|
|||
|
|
@ -73,8 +73,11 @@ export function Lexer(input: string, start: number = 0, end?: number) {
|
|||
if (input[index + 1] === "=") tokens.push(makeToken(input, TokenKind.OPERATOR, index++, 2))
|
||||
else {
|
||||
if (input[index] === input[index + 1]) {
|
||||
if (input[index] !== "!") tokens.push(makeToken(input, TokenKind.OPERATOR, index++, 2))
|
||||
else tokens.push(makeToken(input, TokenKind.OPERATOR, index))
|
||||
if (input[index] !== "!") {
|
||||
if (input[++index] === input[index + 1])
|
||||
tokens.push(makeToken(input, TokenKind.OPERATOR, index++ - 1, 3))
|
||||
else tokens.push(makeToken(input, TokenKind.OPERATOR, index - 1, 2))
|
||||
} else tokens.push(makeToken(input, TokenKind.OPERATOR, index))
|
||||
} else tokens.push(makeToken(input, TokenKind.OPERATOR, index))
|
||||
}
|
||||
break
|
||||
|
|
@ -135,6 +138,7 @@ export function Lexer(input: string, start: number = 0, end?: number) {
|
|||
value: `'${input.slice(start, index - 1)}'`,
|
||||
},
|
||||
})
|
||||
index--
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
@ -199,12 +203,12 @@ export function Lexer(input: string, start: number = 0, end?: number) {
|
|||
)
|
||||
throw new Error()
|
||||
}
|
||||
tokens.push(makeToken(input, TokenKind.NUMBER, start, index - start + 1))
|
||||
tokens.push(makeToken(input, TokenKind.INT, start, index - start + 1))
|
||||
break
|
||||
} else if (numType === "b") {
|
||||
index += 2
|
||||
while (Checker.isBinaryChar(input[index + 1])) index++
|
||||
tokens.push(makeToken(input, TokenKind.NUMBER, start, index - start + 1))
|
||||
tokens.push(makeToken(input, TokenKind.INT, start, index - start + 1))
|
||||
if (start + 2 === index) {
|
||||
console.error(
|
||||
`\x1b[31merror: ${input + "\n" + " ".repeat(index + 6) + "^"}\nInvalid character.\x1b[0m`,
|
||||
|
|
@ -215,7 +219,7 @@ export function Lexer(input: string, start: number = 0, end?: number) {
|
|||
} else if (numType === "o") {
|
||||
index += 2
|
||||
while (Checker.isOctalChar(input[index + 1])) index++
|
||||
tokens.push(makeToken(input, TokenKind.NUMBER, start, index - start + 1))
|
||||
tokens.push(makeToken(input, TokenKind.INT, start, index - start + 1))
|
||||
if (start + 2 === index) {
|
||||
console.error(
|
||||
`\x1b[31merror: ${input + "\n" + " ".repeat(index + 6) + "^"}\nInvalid character.\x1b[0m`,
|
||||
|
|
@ -239,7 +243,7 @@ export function Lexer(input: string, start: number = 0, end?: number) {
|
|||
while (Checker.isNumberChar(input[index + 1])) index++
|
||||
}
|
||||
|
||||
tokens.push(makeToken(input, TokenKind.NUMBER, start, index - start + 1))
|
||||
tokens.push(makeToken(input, TokenKind.INT, start, index - start + 1))
|
||||
} else if (Checker.isWordChar(token)) {
|
||||
while (Checker.isWordChar(input[index + 1])) index++
|
||||
tokens.push(makeToken(input, TokenKind.WORD, start, index - start + 1))
|
||||
|
|
|
|||
|
|
@ -186,110 +186,13 @@ export class Parser {
|
|||
}
|
||||
|
||||
private parseBitwiseLogicExpression(): Expression {
|
||||
let left = this.parseBitwiseShiftExpression(),
|
||||
current
|
||||
|
||||
while (
|
||||
(current = this.at()) &&
|
||||
this.at()?.kind === TokenKind.OPERATOR &&
|
||||
["&", "|", "^"].includes(<string>current.value)
|
||||
) {
|
||||
const operator = this.eat()
|
||||
const right = this.parsePrimaryExpression()
|
||||
|
||||
const cacheStr = `expr:${left}${operator.value}${right}`
|
||||
if (this.cache.has(cacheStr)) {
|
||||
return (left = this.cache.get(cacheStr) as Expression)
|
||||
}
|
||||
|
||||
const ret = RandomBindingString(16)
|
||||
|
||||
this.cache.set(cacheStr, ret)
|
||||
|
||||
const leftBin = this.intToBin(left)
|
||||
const rightBin = this.intToBin(right)
|
||||
|
||||
if (operator.value === "&") {
|
||||
this.genBindings.push(
|
||||
...Array.from({ length: 30 }, (_, i) => {
|
||||
return {
|
||||
source: `(${leftBin}${i} * ${rightBin}${i})`,
|
||||
target: `${ret}${i}`,
|
||||
}
|
||||
}),
|
||||
)
|
||||
} else if (operator.value === "|") {
|
||||
this.genBindings.push(
|
||||
...Array.from({ length: 30 }, (_, i) => {
|
||||
return {
|
||||
source: `(${leftBin}${i} + ${rightBin}${i} - (${leftBin}${i} * ${rightBin}${i}))`,
|
||||
target: `${ret}${i}`,
|
||||
}
|
||||
}),
|
||||
)
|
||||
} else {
|
||||
this.genBindings.push(
|
||||
...Array.from({ length: 30 }, (_, i) => {
|
||||
return {
|
||||
source: `(${leftBin}${i} + ${rightBin}${i} - 2 * (${leftBin}${i} * ${rightBin}${i}))`,
|
||||
target: `${ret}${i}`,
|
||||
}
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
this.genBindings.push({
|
||||
source: `(${Array.from({ length: 30 }, (_, i) => `(${ret}${i} * ${2 ** i})`).join(" + ")})`,
|
||||
target: ret,
|
||||
})
|
||||
|
||||
left = ret
|
||||
}
|
||||
|
||||
return left
|
||||
// TODO
|
||||
return this.parseBitwiseShiftExpression()
|
||||
}
|
||||
|
||||
private parseBitwiseShiftExpression(): Expression {
|
||||
let left = this.parsePrimaryExpression(),
|
||||
current
|
||||
|
||||
while (
|
||||
(current = this.at()) &&
|
||||
this.at()?.kind === TokenKind.OPERATOR &&
|
||||
[">>", "<<"].includes(<string>current.value)
|
||||
) {
|
||||
const operator = this.eat()
|
||||
const right = this.parsePrimaryExpression()
|
||||
|
||||
const cacheStr = `expr:${left}${operator.value}${right}`
|
||||
if (this.cache.has(cacheStr)) {
|
||||
return (left = this.cache.get(cacheStr) as Expression)
|
||||
}
|
||||
const ret = RandomBindingString(16)
|
||||
this.cache.set(cacheStr, ret)
|
||||
|
||||
const leftBind = this.intToBin(left)
|
||||
|
||||
const op = operator.value === "<<" ? "-" : "+"
|
||||
|
||||
this.genBindings.push(
|
||||
...Array.from({ length: 30 }, (_, i) => {
|
||||
return {
|
||||
source: `((0 * ${left}) + ('${leftBind}' + (${i} ${op} ${right})))`,
|
||||
target: `${ret}${i}`,
|
||||
}
|
||||
}),
|
||||
)
|
||||
|
||||
this.genBindings.push({
|
||||
source: `(${Array.from({ length: 30 }, (_, i) => `(${ret}${i} * ${2 ** i})`).join(" + ")})`,
|
||||
target: ret,
|
||||
})
|
||||
|
||||
left = ret
|
||||
}
|
||||
|
||||
return left
|
||||
// TODO
|
||||
return this.parsePrimaryExpression()
|
||||
}
|
||||
|
||||
private parsePrimaryExpression(): Expression {
|
||||
|
|
@ -307,7 +210,7 @@ export class Parser {
|
|||
return `(${value})`
|
||||
}
|
||||
|
||||
case TokenKind.NUMBER: {
|
||||
case TokenKind.INT: {
|
||||
const numberToken = this.eat()
|
||||
|
||||
switch (numberToken.value[1]) {
|
||||
|
|
@ -390,7 +293,7 @@ export class Parser {
|
|||
}
|
||||
|
||||
default:
|
||||
this.expect(TokenKind.NUMBER, "Unexpected token!")
|
||||
this.expect(TokenKind.INT, "Unexpected token!")
|
||||
}
|
||||
|
||||
return left.value
|
||||
|
|
@ -404,7 +307,7 @@ export class Parser {
|
|||
const args: Expression[] = []
|
||||
|
||||
if (this.at().kind === TokenKind.COMMA) {
|
||||
this.expect(TokenKind.NUMBER, "Unexpected token!")
|
||||
this.expect(TokenKind.INT, "Unexpected token!")
|
||||
}
|
||||
|
||||
if (this.at().kind !== TokenKind.CLOSE_PARENTHESIS) {
|
||||
|
|
@ -413,7 +316,7 @@ export class Parser {
|
|||
while (this.at().kind === TokenKind.COMMA) {
|
||||
this.eat()
|
||||
if (this.at().kind === TokenKind.CLOSE_PARENTHESIS) {
|
||||
this.expect(TokenKind.NUMBER, "Unexpected token!")
|
||||
this.expect(TokenKind.INT, "Unexpected token!")
|
||||
}
|
||||
args.push(this.parseExpression())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
export enum TokenKind {
|
||||
VARIABLE,
|
||||
NUMBER,
|
||||
STRING,
|
||||
TEMPLATE_STRING,
|
||||
WORD,
|
||||
|
||||
INT,
|
||||
FLOAT,
|
||||
|
||||
OPEN_PARENTHESIS,
|
||||
CLOSE_PARENTHESIS,
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ if (isBuildMode) {
|
|||
let first = true
|
||||
process.on("beforeExit", async () => {
|
||||
if (first) {
|
||||
first = false
|
||||
await createBuildFolder()
|
||||
await buildUI()
|
||||
if (isLinkMode) await linkToGame()
|
||||
|
|
@ -85,7 +86,6 @@ if (isBuildMode) {
|
|||
console.log("Install Path:", `\x1b[32m"${path.join(gamePath, await getBuildFolderName())}"\x1b[0m`)
|
||||
console.log("=============================================================")
|
||||
}
|
||||
first = false
|
||||
})
|
||||
} else if (isLinkMode) linkToGame()
|
||||
else if (unLinked) unlink()
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ export class UI<T extends Type, K extends Renderer | null = null> extends Class
|
|||
|
||||
if (this.controls.size) {
|
||||
obj.controls = []
|
||||
this.controls.forEach((e, key) => obj.controls.push({ [key + e[0]]: e[1] }))
|
||||
this.controls.forEach((e, key) => obj.controls.push({ [key + e[0]]: FormatProperties(e[1]) }))
|
||||
}
|
||||
|
||||
return obj
|
||||
|
|
|
|||
|
|
@ -15,4 +15,4 @@ export { ItemAuxID } from "./types/enums/Items.js"
|
|||
|
||||
export { ArrayName, Operation } from "./types/properties/index.js"
|
||||
|
||||
export { Lexer } from "./compilers/bindings/Lexer.js"
|
||||
export * from "./compilers/bindings/Binary.js"
|
||||
|
|
|
|||
Reference in a new issue