@witchcraft/expressit 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +86 -0
- package/dist/ast/builders/array.d.ts +8 -0
- package/dist/ast/builders/array.d.ts.map +1 -0
- package/dist/ast/builders/array.js +31 -0
- package/dist/ast/builders/condition.d.ts +20 -0
- package/dist/ast/builders/condition.d.ts.map +1 -0
- package/dist/ast/builders/condition.js +28 -0
- package/dist/ast/builders/delim.d.ts +11 -0
- package/dist/ast/builders/delim.d.ts.map +1 -0
- package/dist/ast/builders/delim.js +20 -0
- package/dist/ast/builders/error.d.ts +9 -0
- package/dist/ast/builders/error.d.ts.map +1 -0
- package/dist/ast/builders/error.js +16 -0
- package/dist/ast/builders/expression.d.ts +12 -0
- package/dist/ast/builders/expression.d.ts.map +1 -0
- package/dist/ast/builders/expression.js +31 -0
- package/dist/ast/builders/group.d.ts +20 -0
- package/dist/ast/builders/group.d.ts.map +1 -0
- package/dist/ast/builders/group.js +47 -0
- package/dist/ast/builders/index.d.ts +12 -0
- package/dist/ast/builders/index.d.ts.map +1 -0
- package/dist/ast/builders/index.js +24 -0
- package/dist/ast/builders/isFullPos.d.ts +6 -0
- package/dist/ast/builders/isFullPos.d.ts.map +1 -0
- package/dist/ast/builders/isFullPos.js +6 -0
- package/dist/ast/builders/pos.d.ts +21 -0
- package/dist/ast/builders/pos.d.ts.map +1 -0
- package/dist/ast/builders/pos.js +28 -0
- package/dist/ast/builders/token.d.ts +12 -0
- package/dist/ast/builders/token.d.ts.map +1 -0
- package/dist/ast/builders/token.js +26 -0
- package/dist/ast/builders/type.d.ts +6 -0
- package/dist/ast/builders/type.d.ts.map +1 -0
- package/dist/ast/builders/type.js +37 -0
- package/dist/ast/builders/variable.d.ts +17 -0
- package/dist/ast/builders/variable.d.ts.map +1 -0
- package/dist/ast/builders/variable.js +62 -0
- package/dist/ast/classes/ArrayNode.d.ts +18 -0
- package/dist/ast/classes/ArrayNode.d.ts.map +1 -0
- package/dist/ast/classes/ArrayNode.js +55 -0
- package/dist/ast/classes/Condition.d.ts +13 -0
- package/dist/ast/classes/Condition.d.ts.map +1 -0
- package/dist/ast/classes/Condition.js +21 -0
- package/dist/ast/classes/ConditionNode.d.ts +73 -0
- package/dist/ast/classes/ConditionNode.d.ts.map +1 -0
- package/dist/ast/classes/ConditionNode.js +101 -0
- package/dist/ast/classes/ErrorToken.d.ts +27 -0
- package/dist/ast/classes/ErrorToken.d.ts.map +1 -0
- package/dist/ast/classes/ErrorToken.js +47 -0
- package/dist/ast/classes/Expression.d.ts +13 -0
- package/dist/ast/classes/Expression.d.ts.map +1 -0
- package/dist/ast/classes/Expression.js +19 -0
- package/dist/ast/classes/ExpressionNode.d.ts +21 -0
- package/dist/ast/classes/ExpressionNode.d.ts.map +1 -0
- package/dist/ast/classes/ExpressionNode.js +57 -0
- package/dist/ast/classes/GroupNode.d.ts +64 -0
- package/dist/ast/classes/GroupNode.d.ts.map +1 -0
- package/dist/ast/classes/GroupNode.js +69 -0
- package/dist/ast/classes/Node.d.ts +22 -0
- package/dist/ast/classes/Node.d.ts.map +1 -0
- package/dist/ast/classes/Node.js +28 -0
- package/dist/ast/classes/Token.d.ts +27 -0
- package/dist/ast/classes/Token.d.ts.map +1 -0
- package/dist/ast/classes/Token.js +28 -0
- package/dist/ast/classes/ValidToken.d.ts +26 -0
- package/dist/ast/classes/ValidToken.d.ts.map +1 -0
- package/dist/ast/classes/ValidToken.js +49 -0
- package/dist/ast/classes/VariableNode.d.ts +33 -0
- package/dist/ast/classes/VariableNode.d.ts.map +1 -0
- package/dist/ast/classes/VariableNode.js +58 -0
- package/dist/ast/classes/index.d.ts +12 -0
- package/dist/ast/classes/index.d.ts.map +1 -0
- package/dist/ast/classes/index.js +24 -0
- package/dist/ast/handlers.d.ts +42 -0
- package/dist/ast/handlers.d.ts.map +1 -0
- package/dist/ast/handlers.js +150 -0
- package/dist/ast/index.d.ts +4 -0
- package/dist/ast/index.d.ts.map +1 -0
- package/dist/ast/index.js +8 -0
- package/dist/examples/advancedValueComparer.d.ts +3 -0
- package/dist/examples/advancedValueComparer.d.ts.map +1 -0
- package/dist/examples/advancedValueComparer.js +28 -0
- package/dist/examples/shortcutContextParser.d.ts +22 -0
- package/dist/examples/shortcutContextParser.d.ts.map +1 -0
- package/dist/examples/shortcutContextParser.js +126 -0
- package/dist/global.d.js +1 -0
- package/dist/grammar/ParserBase.d.ts +51 -0
- package/dist/grammar/ParserBase.d.ts.map +1 -0
- package/dist/grammar/ParserBase.js +516 -0
- package/dist/grammar/createTokens.d.ts +56 -0
- package/dist/grammar/createTokens.d.ts.map +1 -0
- package/dist/grammar/createTokens.js +843 -0
- package/dist/grammar/index.d.ts +3 -0
- package/dist/grammar/index.d.ts.map +1 -0
- package/dist/grammar/index.js +6 -0
- package/dist/helpers/errors.d.ts +9 -0
- package/dist/helpers/errors.d.ts.map +1 -0
- package/dist/helpers/errors.js +41 -0
- package/dist/helpers/general/applyBoolean.d.ts +3 -0
- package/dist/helpers/general/applyBoolean.d.ts.map +1 -0
- package/dist/helpers/general/applyBoolean.js +17 -0
- package/dist/helpers/general/applyPrefix.d.ts +4 -0
- package/dist/helpers/general/applyPrefix.d.ts.map +1 -0
- package/dist/helpers/general/applyPrefix.js +9 -0
- package/dist/helpers/general/defaultConditionNormalizer.d.ts +3 -0
- package/dist/helpers/general/defaultConditionNormalizer.d.ts.map +1 -0
- package/dist/helpers/general/defaultConditionNormalizer.js +6 -0
- package/dist/helpers/general/defaultKeyParser.d.ts +3 -0
- package/dist/helpers/general/defaultKeyParser.d.ts.map +1 -0
- package/dist/helpers/general/defaultKeyParser.js +8 -0
- package/dist/helpers/general/defaultPrefixApplier.d.ts +3 -0
- package/dist/helpers/general/defaultPrefixApplier.d.ts.map +1 -0
- package/dist/helpers/general/defaultPrefixApplier.js +6 -0
- package/dist/helpers/general/defaultValueComparer.d.ts +3 -0
- package/dist/helpers/general/defaultValueComparer.d.ts.map +1 -0
- package/dist/helpers/general/defaultValueComparer.js +6 -0
- package/dist/helpers/general/index.d.ts +7 -0
- package/dist/helpers/general/index.d.ts.map +1 -0
- package/dist/helpers/general/index.js +14 -0
- package/dist/helpers/index.d.ts +4 -0
- package/dist/helpers/index.d.ts.map +1 -0
- package/dist/helpers/index.js +8 -0
- package/dist/helpers/parser/assignParents.d.ts +4 -0
- package/dist/helpers/parser/assignParents.d.ts.map +1 -0
- package/dist/helpers/parser/assignParents.js +71 -0
- package/dist/helpers/parser/checkParserOpts.d.ts +3 -0
- package/dist/helpers/parser/checkParserOpts.d.ts.map +1 -0
- package/dist/helpers/parser/checkParserOpts.js +126 -0
- package/dist/helpers/parser/extractPosition.d.ts +9 -0
- package/dist/helpers/parser/extractPosition.d.ts.map +1 -0
- package/dist/helpers/parser/extractPosition.js +9 -0
- package/dist/helpers/parser/getUnclosedRightParenCount.d.ts +5 -0
- package/dist/helpers/parser/getUnclosedRightParenCount.d.ts.map +1 -0
- package/dist/helpers/parser/getUnclosedRightParenCount.js +20 -0
- package/dist/helpers/parser/index.d.ts +9 -0
- package/dist/helpers/parser/index.d.ts.map +1 -0
- package/dist/helpers/parser/index.js +18 -0
- package/dist/helpers/parser/parseParserOptions.d.ts +4 -0
- package/dist/helpers/parser/parseParserOptions.d.ts.map +1 -0
- package/dist/helpers/parser/parseParserOptions.js +45 -0
- package/dist/helpers/parser/seal.d.ts +8 -0
- package/dist/helpers/parser/seal.d.ts.map +1 -0
- package/dist/helpers/parser/seal.js +10 -0
- package/dist/helpers/parser/setParent.d.ts +6 -0
- package/dist/helpers/parser/setParent.d.ts.map +1 -0
- package/dist/helpers/parser/setParent.js +4 -0
- package/dist/helpers/parser/unescape.d.ts +3 -0
- package/dist/helpers/parser/unescape.d.ts.map +1 -0
- package/dist/helpers/parser/unescape.js +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/methods/autocomplete.d.ts +18 -0
- package/dist/methods/autocomplete.d.ts.map +1 -0
- package/dist/methods/autocomplete.js +109 -0
- package/dist/methods/autoreplace.d.ts +13 -0
- package/dist/methods/autoreplace.d.ts.map +1 -0
- package/dist/methods/autoreplace.js +36 -0
- package/dist/methods/autosuggest.d.ts +28 -0
- package/dist/methods/autosuggest.d.ts.map +1 -0
- package/dist/methods/autosuggest.js +371 -0
- package/dist/methods/evaluate.d.ts +11 -0
- package/dist/methods/evaluate.d.ts.map +1 -0
- package/dist/methods/evaluate.js +30 -0
- package/dist/methods/getBestIndex.d.ts +19 -0
- package/dist/methods/getBestIndex.d.ts.map +1 -0
- package/dist/methods/getBestIndex.js +53 -0
- package/dist/methods/getIndexes.d.ts +17 -0
- package/dist/methods/getIndexes.d.ts.map +1 -0
- package/dist/methods/getIndexes.js +97 -0
- package/dist/methods/index.d.ts +9 -0
- package/dist/methods/index.d.ts.map +1 -0
- package/dist/methods/index.js +18 -0
- package/dist/methods/normalize.d.ts +12 -0
- package/dist/methods/normalize.d.ts.map +1 -0
- package/dist/methods/normalize.js +99 -0
- package/dist/methods/validate.d.ts +11 -0
- package/dist/methods/validate.d.ts.map +1 -0
- package/dist/methods/validate.js +111 -0
- package/dist/package.js +7 -0
- package/dist/package.json.js +193 -0
- package/dist/parser.d.ts +58 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +136 -0
- package/dist/types/ast.d.ts +70 -0
- package/dist/types/ast.d.ts.map +1 -0
- package/dist/types/ast.js +29 -0
- package/dist/types/autocomplete.d.ts +143 -0
- package/dist/types/autocomplete.d.ts.map +1 -0
- package/dist/types/autocomplete.js +24 -0
- package/dist/types/errors.d.ts +34 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +10 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +9 -0
- package/dist/types/parser.d.ts +451 -0
- package/dist/types/parser.d.ts.map +1 -0
- package/dist/types/parser.js +1 -0
- package/dist/utils/extractTokens.d.ts +8 -0
- package/dist/utils/extractTokens.d.ts.map +1 -0
- package/dist/utils/extractTokens.js +50 -0
- package/dist/utils/getCursorInfo.d.ts +7 -0
- package/dist/utils/getCursorInfo.d.ts.map +1 -0
- package/dist/utils/getCursorInfo.js +86 -0
- package/dist/utils/getOppositeDelimiter.d.ts +6 -0
- package/dist/utils/getOppositeDelimiter.d.ts.map +1 -0
- package/dist/utils/getOppositeDelimiter.js +35 -0
- package/dist/utils/getSurroundingErrors.d.ts +25 -0
- package/dist/utils/getSurroundingErrors.d.ts.map +1 -0
- package/dist/utils/getSurroundingErrors.js +37 -0
- package/dist/utils/index.d.ts +10 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +20 -0
- package/dist/utils/isBracket.d.ts +3 -0
- package/dist/utils/isBracket.d.ts.map +1 -0
- package/dist/utils/isBracket.js +7 -0
- package/dist/utils/isDelimiter.d.ts +6 -0
- package/dist/utils/isDelimiter.d.ts.map +1 -0
- package/dist/utils/isDelimiter.js +17 -0
- package/dist/utils/isParen.d.ts +3 -0
- package/dist/utils/isParen.d.ts.map +1 -0
- package/dist/utils/isParen.js +7 -0
- package/dist/utils/isQuote.d.ts +4 -0
- package/dist/utils/isQuote.d.ts.map +1 -0
- package/dist/utils/isQuote.js +7 -0
- package/dist/utils/prettyAst.d.ts +35 -0
- package/dist/utils/prettyAst.d.ts.map +1 -0
- package/dist/utils/prettyAst.js +112 -0
- package/package.json +152 -0
- package/src/ast/builders/array.ts +45 -0
- package/src/ast/builders/condition.ts +56 -0
- package/src/ast/builders/delim.ts +39 -0
- package/src/ast/builders/error.ts +22 -0
- package/src/ast/builders/expression.ts +66 -0
- package/src/ast/builders/group.ts +79 -0
- package/src/ast/builders/index.ts +13 -0
- package/src/ast/builders/isFullPos.ts +10 -0
- package/src/ast/builders/pos.ts +57 -0
- package/src/ast/builders/token.ts +46 -0
- package/src/ast/builders/type.ts +32 -0
- package/src/ast/builders/variable.ts +89 -0
- package/src/ast/classes/ArrayNode.ts +46 -0
- package/src/ast/classes/Condition.ts +22 -0
- package/src/ast/classes/ConditionNode.ts +141 -0
- package/src/ast/classes/ErrorToken.ts +49 -0
- package/src/ast/classes/Expression.ts +26 -0
- package/src/ast/classes/ExpressionNode.ts +62 -0
- package/src/ast/classes/GroupNode.ts +127 -0
- package/src/ast/classes/Node.ts +47 -0
- package/src/ast/classes/Token.ts +59 -0
- package/src/ast/classes/ValidToken.ts +56 -0
- package/src/ast/classes/VariableNode.ts +67 -0
- package/src/ast/classes/index.ts +13 -0
- package/src/ast/handlers.ts +190 -0
- package/src/ast/index.ts +5 -0
- package/src/examples/advancedValueComparer.ts +31 -0
- package/src/examples/shortcutContextParser.ts +140 -0
- package/src/global.d.ts +4 -0
- package/src/grammar/ParserBase.ts +715 -0
- package/src/grammar/createTokens.ts +512 -0
- package/src/grammar/index.ts +4 -0
- package/src/helpers/errors.ts +45 -0
- package/src/helpers/general/applyBoolean.ts +9 -0
- package/src/helpers/general/applyPrefix.ts +7 -0
- package/src/helpers/general/defaultConditionNormalizer.ts +9 -0
- package/src/helpers/general/defaultKeyParser.ts +8 -0
- package/src/helpers/general/defaultPrefixApplier.ts +7 -0
- package/src/helpers/general/defaultValueComparer.ts +7 -0
- package/src/helpers/general/index.ts +8 -0
- package/src/helpers/index.ts +5 -0
- package/src/helpers/parser/assignParents.ts +51 -0
- package/src/helpers/parser/checkParserOpts.ts +143 -0
- package/src/helpers/parser/extractPosition.ts +15 -0
- package/src/helpers/parser/getUnclosedRightParenCount.ts +22 -0
- package/src/helpers/parser/index.ts +10 -0
- package/src/helpers/parser/parseParserOptions.ts +54 -0
- package/src/helpers/parser/seal.ts +14 -0
- package/src/helpers/parser/setParent.ts +5 -0
- package/src/helpers/parser/unescape.ts +4 -0
- package/src/index.ts +7 -0
- package/src/methods/autocomplete.ts +128 -0
- package/src/methods/autoreplace.ts +46 -0
- package/src/methods/autosuggest.ts +543 -0
- package/src/methods/evaluate.ts +37 -0
- package/src/methods/getBestIndex.ts +53 -0
- package/src/methods/getIndexes.ts +99 -0
- package/src/methods/index.ts +10 -0
- package/src/methods/normalize.ts +138 -0
- package/src/methods/validate.ts +141 -0
- package/src/package.js +11 -0
- package/src/parser.ts +183 -0
- package/src/types/ast.ts +148 -0
- package/src/types/autocomplete.ts +152 -0
- package/src/types/errors.ts +40 -0
- package/src/types/index.ts +6 -0
- package/src/types/parser.ts +479 -0
- package/src/utils/extractTokens.ts +67 -0
- package/src/utils/getCursorInfo.ts +106 -0
- package/src/utils/getOppositeDelimiter.ts +36 -0
- package/src/utils/getSurroundingErrors.ts +57 -0
- package/src/utils/index.ts +11 -0
- package/src/utils/isBracket.ts +6 -0
- package/src/utils/isDelimiter.ts +18 -0
- package/src/utils/isParen.ts +6 -0
- package/src/utils/isQuote.ts +6 -0
- package/src/utils/prettyAst.ts +152 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Mutable } from "@alanscodelog/utils"
|
|
2
|
+
|
|
3
|
+
import { token } from "./token.js"
|
|
4
|
+
|
|
5
|
+
import { AST_TYPE, type Position, TOKEN_TYPE } from "../../types/ast.js"
|
|
6
|
+
import { ArrayNode } from "../classes/ArrayNode.js"
|
|
7
|
+
import type { VariableNode } from "../classes/VariableNode.js"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
export function array(
|
|
11
|
+
values: VariableNode[],
|
|
12
|
+
bracket: { left?: boolean, right?: boolean } = { right: true, left: true },
|
|
13
|
+
parenLeftPos?: Position,
|
|
14
|
+
parenRightPos?: Position
|
|
15
|
+
): ArrayNode {
|
|
16
|
+
const node: Mutable<Partial<ArrayNode>> = {
|
|
17
|
+
type: AST_TYPE.ARRAY,
|
|
18
|
+
values,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
node.bracket = {} as any
|
|
22
|
+
|
|
23
|
+
const start = values[0]?.start ?? parenLeftPos?.end
|
|
24
|
+
const end = values[values.length - 1]?.end ?? parenRightPos?.start ?? parenLeftPos?.end
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
parenLeftPos ??= (start !== undefined ? { start: start - 1, end: start } : undefined)
|
|
28
|
+
parenRightPos ??= (end !== undefined ? { start: end, end: end + 1 } : undefined)
|
|
29
|
+
|
|
30
|
+
// is always valid for now
|
|
31
|
+
node.bracket!.left = token(TOKEN_TYPE.BRACKETL, "[", parenLeftPos)
|
|
32
|
+
|
|
33
|
+
if (bracket?.right) {
|
|
34
|
+
node.bracket!.right = token(TOKEN_TYPE.BRACKETR, "]", parenRightPos)
|
|
35
|
+
} else {
|
|
36
|
+
if (parenRightPos) { parenRightPos.end = parenRightPos.start }
|
|
37
|
+
node.bracket!.right = token(TOKEN_TYPE.BRACKETR, undefined, parenRightPos)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
node.start = node.bracket!.left?.start ?? start ?? node.bracket?.right.start
|
|
41
|
+
node.end = node.bracket?.right?.end ?? end ?? node.bracket!.left.end
|
|
42
|
+
|
|
43
|
+
const instance = new ArrayNode(node as any)
|
|
44
|
+
return instance
|
|
45
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { pos } from "./pos.js"
|
|
2
|
+
|
|
3
|
+
import { type AnyToken, type Position, type TOKEN_TYPE } from "../../types/ast.js"
|
|
4
|
+
import type { ArrayNode } from "../classes/ArrayNode.js"
|
|
5
|
+
import { ConditionNode } from "../classes/ConditionNode.js"
|
|
6
|
+
import type { ErrorToken } from "../classes/ErrorToken.js"
|
|
7
|
+
import type { GroupNode } from "../classes/GroupNode.js"
|
|
8
|
+
import type { ValidToken } from "../classes/ValidToken.js"
|
|
9
|
+
import type { VariableNode } from "../classes/VariableNode.js"
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Creates a @see ConditionNode
|
|
13
|
+
*
|
|
14
|
+
* @param variable An existing @see VariableNode
|
|
15
|
+
*
|
|
16
|
+
* @param not Defaults to plain true condition. To negate it you must pass an existing "not" operator @see ValidToken which will be set as the node's operator and set the node's value to false.
|
|
17
|
+
*
|
|
18
|
+
* @param property Set the property for a property operator. A property operator must be passed if this is passed.
|
|
19
|
+
* @param propertyOperator Set the operator for a property condition. A property must have been passed. The property operator must be a valid token. There is no case where it would not be. If using an operator that is the same as a separator, if used as an operator, should be set as an operator.
|
|
20
|
+
* @param sep Pass separator tokens for expanded property conditions.
|
|
21
|
+
*/
|
|
22
|
+
// todo doc property operator
|
|
23
|
+
export function condition(
|
|
24
|
+
value:
|
|
25
|
+
| VariableNode
|
|
26
|
+
| GroupNode
|
|
27
|
+
| ArrayNode
|
|
28
|
+
| ErrorToken<TOKEN_TYPE.VALUE>,
|
|
29
|
+
not: true | ValidToken<TOKEN_TYPE.NOT> = true,
|
|
30
|
+
property?: VariableNode | ErrorToken<TOKEN_TYPE.VALUE>,
|
|
31
|
+
propertyOperator?: AnyToken<TOKEN_TYPE.OP_CUSTOM | TOKEN_TYPE.VALUE>,
|
|
32
|
+
{ right, left }: Partial<Record<"right" | "left", ValidToken<TOKEN_TYPE.OP_EXPANDED_SEP>>> = { }
|
|
33
|
+
): ConditionNode {
|
|
34
|
+
const position = pos(value satisfies Position)
|
|
35
|
+
const notStart = not === true ? undefined : not.start
|
|
36
|
+
position.start = notStart ?? property?.start ?? propertyOperator?.start ?? position.start
|
|
37
|
+
|
|
38
|
+
const node: Partial<ConstructorParameters<typeof ConditionNode>[0]> = {
|
|
39
|
+
property,
|
|
40
|
+
value,
|
|
41
|
+
propertyOperator,
|
|
42
|
+
...position,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (not !== true) {
|
|
46
|
+
node.operator = not
|
|
47
|
+
}
|
|
48
|
+
if (right || left) {
|
|
49
|
+
node.sep = {}
|
|
50
|
+
if (right) node.sep.right = right
|
|
51
|
+
if (left) node.sep.left = left
|
|
52
|
+
}
|
|
53
|
+
const instance = new ConditionNode(node as any)
|
|
54
|
+
return instance
|
|
55
|
+
}
|
|
56
|
+
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type } from "./type.js"
|
|
2
|
+
|
|
3
|
+
import { type ExtractTokenType, TOKEN_TYPE } from "../../types/ast.js"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Faster way, more intuitive way to generate the options for matching delimiters (e.g. quotes and parens) for functions like @see variable and @see group .
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export function delim<
|
|
10
|
+
TLeft extends boolean | string,
|
|
11
|
+
TRight extends boolean | string,
|
|
12
|
+
TType extends TLeft extends string
|
|
13
|
+
? ExtractTokenType<TLeft>
|
|
14
|
+
: TRight extends string
|
|
15
|
+
? ExtractTokenType<TRight>
|
|
16
|
+
: undefined,
|
|
17
|
+
>(
|
|
18
|
+
left: TLeft = false as TLeft,
|
|
19
|
+
right: TRight = false as TRight,
|
|
20
|
+
):
|
|
21
|
+
{
|
|
22
|
+
left: TLeft extends string ? true : TLeft
|
|
23
|
+
right: TRight extends string ? true : TRight
|
|
24
|
+
} & TType extends undefined ? {} : { type: TType } {
|
|
25
|
+
let quoteType
|
|
26
|
+
if (typeof left === "string") quoteType = type(left)
|
|
27
|
+
else if (typeof right === "string") quoteType = type(right)
|
|
28
|
+
|
|
29
|
+
const opts: any = {
|
|
30
|
+
left: left === true || (typeof left === "string" && left !== undefined),
|
|
31
|
+
right: right === true || (typeof right === "string" && right !== undefined),
|
|
32
|
+
}
|
|
33
|
+
if (quoteType !== undefined &&
|
|
34
|
+
![TOKEN_TYPE.PARENL, TOKEN_TYPE.PARENR].includes(quoteType)
|
|
35
|
+
) {
|
|
36
|
+
opts.type = quoteType
|
|
37
|
+
}
|
|
38
|
+
return opts
|
|
39
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type } from "./type.js"
|
|
2
|
+
|
|
3
|
+
import { TOKEN_TYPE } from "../../types/ast.js"
|
|
4
|
+
import { ErrorToken } from "../classes/ErrorToken.js"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Creates an error token.
|
|
9
|
+
*
|
|
10
|
+
* @param expected Can be passed an array of @see ValidToken_TYPE or strings, in which case it will use @see type internally. So instead of `[TOKEN_TYPE.VALUE]` we can do `[""]` and instead of `[TOKEN_TYPE.PARENR]` we can do `[")"]`.
|
|
11
|
+
*/
|
|
12
|
+
export function error<T extends TOKEN_TYPE>(pos: number, expected: T[]): ErrorToken<T>
|
|
13
|
+
export function error<T extends TOKEN_TYPE>(pos: number, expected_: T[]): ErrorToken<T> {
|
|
14
|
+
const expected = expected_.map(item => {
|
|
15
|
+
if (TOKEN_TYPE[item as keyof typeof TOKEN_TYPE] === undefined) {
|
|
16
|
+
return type(item)
|
|
17
|
+
} else {
|
|
18
|
+
return item
|
|
19
|
+
}
|
|
20
|
+
}) as T []
|
|
21
|
+
return new ErrorToken({ expected, start: pos, end: pos })
|
|
22
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { pos } from "./pos.js"
|
|
2
|
+
import { token } from "./token.js"
|
|
3
|
+
|
|
4
|
+
import { type AnyToken, type Position, TOKEN_TYPE, type TokenBooleanTypes } from "../../types/ast.js"
|
|
5
|
+
import type { ConditionNode } from "../classes/ConditionNode.js"
|
|
6
|
+
import type { ErrorToken } from "../classes/ErrorToken.js"
|
|
7
|
+
import { ExpressionNode } from "../classes/ExpressionNode.js"
|
|
8
|
+
import type { GroupNode } from "../classes/GroupNode.js"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Creates an @see ExpressionNode, can be passed nothing for any of the tokens to automatically create error tokens.
|
|
13
|
+
*
|
|
14
|
+
* Also automatically sets the correct start/end positions from valid tokens (e.g. for start, searching left to right for a valid token and vice versa) assuming at least one is defined.
|
|
15
|
+
*/
|
|
16
|
+
export function expression(
|
|
17
|
+
left:
|
|
18
|
+
ConditionNode |
|
|
19
|
+
ExpressionNode |
|
|
20
|
+
GroupNode |
|
|
21
|
+
ErrorToken<TOKEN_TYPE.VALUE> |
|
|
22
|
+
undefined,
|
|
23
|
+
operator:
|
|
24
|
+
AnyToken<TokenBooleanTypes> |
|
|
25
|
+
undefined,
|
|
26
|
+
right:
|
|
27
|
+
ConditionNode |
|
|
28
|
+
ExpressionNode |
|
|
29
|
+
GroupNode |
|
|
30
|
+
ErrorToken<TOKEN_TYPE.VALUE> |
|
|
31
|
+
undefined
|
|
32
|
+
): ExpressionNode {
|
|
33
|
+
const start =
|
|
34
|
+
left?.start ??
|
|
35
|
+
operator?.start ??
|
|
36
|
+
right?.start
|
|
37
|
+
const end =
|
|
38
|
+
right?.end ??
|
|
39
|
+
operator?.end ??
|
|
40
|
+
left?.end
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
const position = pos({ start, end } as Position)
|
|
44
|
+
|
|
45
|
+
if (left === undefined) {
|
|
46
|
+
left = token(TOKEN_TYPE.VALUE, undefined, { start: position.start })
|
|
47
|
+
}
|
|
48
|
+
let op!: ExpressionNode["operator"]
|
|
49
|
+
if (operator === undefined) {
|
|
50
|
+
operator = token([TOKEN_TYPE.AND, TOKEN_TYPE.OR], undefined, { start: left.end })
|
|
51
|
+
} else op = operator
|
|
52
|
+
|
|
53
|
+
if (right === undefined) {
|
|
54
|
+
right = token(TOKEN_TYPE.VALUE, undefined, { start: op.end })
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const node: ConstructorParameters<typeof ExpressionNode>[0] = {
|
|
58
|
+
left,
|
|
59
|
+
operator: op,
|
|
60
|
+
right,
|
|
61
|
+
...position,
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const instance = new ExpressionNode(node)
|
|
65
|
+
return instance
|
|
66
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { token } from "./token.js"
|
|
2
|
+
|
|
3
|
+
import { type Position, TOKEN_TYPE } from "../../types/ast.js"
|
|
4
|
+
import type { ConditionNode } from "../classes/ConditionNode.js"
|
|
5
|
+
import type { ErrorToken } from "../classes/ErrorToken.js"
|
|
6
|
+
import type { ExpressionNode } from "../classes/ExpressionNode.js"
|
|
7
|
+
import { GroupNode } from "../classes/GroupNode.js"
|
|
8
|
+
import type { ValidToken } from "../classes/ValidToken.js"
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Creates a group.
|
|
12
|
+
*
|
|
13
|
+
* Automatically creates error tokens if missing condition or parens (not prefix because it is optional). Will look at the position of prefix if available.
|
|
14
|
+
*
|
|
15
|
+
* @param paren Use to add parens to group, usually by using @see delim . If either `right` or `left` are false or undefined, error tokens will be created. Unlike @see variable, if undefined is passed for parens, parens are created by default.
|
|
16
|
+
*
|
|
17
|
+
* The positions of the parens can be adjusted with the last two parameters by passing positions.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
export function group(
|
|
21
|
+
prefix:
|
|
22
|
+
| ConditionNode
|
|
23
|
+
| ValidToken<TOKEN_TYPE.NOT>
|
|
24
|
+
| undefined,
|
|
25
|
+
|
|
26
|
+
expression:
|
|
27
|
+
| ConditionNode
|
|
28
|
+
| ExpressionNode
|
|
29
|
+
| GroupNode
|
|
30
|
+
| ErrorToken<TOKEN_TYPE.VALUE>
|
|
31
|
+
| undefined,
|
|
32
|
+
|
|
33
|
+
paren: { left?: boolean, right?: boolean } = { right: true, left: true },
|
|
34
|
+
parenLeftPos?: Position,
|
|
35
|
+
parenRightPos?: Position
|
|
36
|
+
): GroupNode {
|
|
37
|
+
if (expression === undefined) {
|
|
38
|
+
expression = token(TOKEN_TYPE.VALUE, undefined, prefix?.end !== undefined ? { start: prefix.end } : undefined)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const node: Partial<ConstructorParameters<typeof GroupNode>[0]> = {
|
|
42
|
+
expression,
|
|
43
|
+
}
|
|
44
|
+
if (prefix) {
|
|
45
|
+
node.prefix = prefix
|
|
46
|
+
const locToRight = node.paren?.left?.start ?? node.expression?.start ?? node.paren?.right.start
|
|
47
|
+
if (prefix.start === undefined && locToRight !== undefined) {
|
|
48
|
+
throw new Error("group builder: missing prefix location when passed expression with location")
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
node.paren = {} as any
|
|
53
|
+
|
|
54
|
+
const start = expression.start
|
|
55
|
+
const end = expression.end
|
|
56
|
+
|
|
57
|
+
parenLeftPos ??= (start !== undefined ? { start: start - 1, end: start } : undefined)
|
|
58
|
+
parenRightPos ??= (end !== undefined ? { start: end, end: end + 1 } : undefined)
|
|
59
|
+
|
|
60
|
+
if (paren?.left) {
|
|
61
|
+
node.paren!.left = token(TOKEN_TYPE.PARENL, "(", parenLeftPos)
|
|
62
|
+
} else {
|
|
63
|
+
if (parenLeftPos) {parenLeftPos.start = parenLeftPos.end}
|
|
64
|
+
node.paren!.left = token(TOKEN_TYPE.PARENL, undefined, parenLeftPos)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (paren?.right) {
|
|
68
|
+
node.paren!.right = token(TOKEN_TYPE.PARENR, ")", parenRightPos)
|
|
69
|
+
} else {
|
|
70
|
+
if (parenRightPos) {parenRightPos.end = parenRightPos.start}
|
|
71
|
+
node.paren!.right = token(TOKEN_TYPE.PARENR, undefined, parenRightPos)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
node.start = node.prefix?.start ?? node.paren?.left?.start ?? node.expression?.start ?? node.paren?.right.start
|
|
75
|
+
node.end = node.paren?.right?.end ?? node.expression?.end ?? node.paren?.left.end ?? node.prefix?.end
|
|
76
|
+
|
|
77
|
+
const instance = new GroupNode(node as any)
|
|
78
|
+
return instance
|
|
79
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/* Autogenerated Index */
|
|
2
|
+
|
|
3
|
+
export { array } from "./array.js"
|
|
4
|
+
export { condition } from "./condition.js"
|
|
5
|
+
export { delim } from "./delim.js"
|
|
6
|
+
export { error } from "./error.js"
|
|
7
|
+
export { expression } from "./expression.js"
|
|
8
|
+
export { group } from "./group.js"
|
|
9
|
+
export { isFullPos } from "./isFullPos.js"
|
|
10
|
+
export { pos } from "./pos.js"
|
|
11
|
+
export { token } from "./token.js"
|
|
12
|
+
export { type } from "./type.js"
|
|
13
|
+
export { variable } from "./variable.js"
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Position } from "../../types/ast.js"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
export function isFullPos(position?: Partial<Position> | any): position is Position {
|
|
7
|
+
return typeof position === "object" &&
|
|
8
|
+
position.start !== undefined &&
|
|
9
|
+
position.end !== undefined
|
|
10
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { isFullPos } from "./isFullPos.js"
|
|
2
|
+
|
|
3
|
+
import type { AnyToken, AST_TYPE, EmptyObj, Position, TOKEN_TYPE } from "../../types/ast.js"
|
|
4
|
+
import type { Node } from "../classes/Node.js"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Can either:
|
|
8
|
+
*
|
|
9
|
+
* - Create a position from two numbers.
|
|
10
|
+
* - Extract just a position from anything with a (full) position.
|
|
11
|
+
* - From a partial position if `{fill:true}`.
|
|
12
|
+
*/
|
|
13
|
+
export function pos<TItem extends Position | Partial<Position> | EmptyObj>(
|
|
14
|
+
item: TItem,
|
|
15
|
+
opts: { fill: true }
|
|
16
|
+
): TItem extends { start: number } | { end: number }
|
|
17
|
+
? Position
|
|
18
|
+
: EmptyObj
|
|
19
|
+
export function pos<TItem extends Position | Partial<Position> | EmptyObj>(
|
|
20
|
+
item: TItem,
|
|
21
|
+
opts?: undefined | { fill: false }
|
|
22
|
+
):
|
|
23
|
+
// not sure why this needs the AnyToken check, prob something to do with using classes
|
|
24
|
+
TItem extends Position
|
|
25
|
+
? Position
|
|
26
|
+
: TItem extends AnyToken<TOKEN_TYPE> | Position | EmptyObj
|
|
27
|
+
? Position | EmptyObj
|
|
28
|
+
: TItem extends Node<AST_TYPE> | Position | EmptyObj
|
|
29
|
+
? Position | EmptyObj
|
|
30
|
+
: EmptyObj
|
|
31
|
+
export function pos(start: number, end: number): Position
|
|
32
|
+
export function pos(
|
|
33
|
+
start: number | Position | Partial<Position> | EmptyObj | undefined,
|
|
34
|
+
end?: number | { fill: boolean }
|
|
35
|
+
): Position | EmptyObj {
|
|
36
|
+
if (typeof start === "number") {
|
|
37
|
+
return { start, end: end as number }
|
|
38
|
+
} else {
|
|
39
|
+
const item = start
|
|
40
|
+
if (item === undefined) return {} as any
|
|
41
|
+
const fill = typeof end === "object" ? end.fill : false
|
|
42
|
+
|
|
43
|
+
if (isFullPos(item)) {
|
|
44
|
+
return { start: item.start, end: item.end }
|
|
45
|
+
} else {
|
|
46
|
+
if (fill) {
|
|
47
|
+
/* eslint-disable @typescript-eslint/no-shadow */
|
|
48
|
+
let start = item.start
|
|
49
|
+
let end = item.end
|
|
50
|
+
if (start !== undefined && end === undefined) end = start
|
|
51
|
+
if (end !== undefined && start === undefined) start = end
|
|
52
|
+
return { start: start!, end: end! }
|
|
53
|
+
}
|
|
54
|
+
return {} as any
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { isArray } from "@alanscodelog/utils"
|
|
2
|
+
|
|
3
|
+
import { pos } from "./pos.js"
|
|
4
|
+
|
|
5
|
+
import type { AnyToken, EmptyObj, Position, TOKEN_TYPE } from "../../types/ast.js"
|
|
6
|
+
import { ErrorToken } from "../classes/ErrorToken.js"
|
|
7
|
+
import { ValidToken } from "../classes/ValidToken.js"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Creates a @see ValidToken or of the given type with the given value. If no value is given, creates an @see ErrorToken instead.
|
|
12
|
+
*
|
|
13
|
+
* Can be passed multiple types when creating an error token to set the expected field.
|
|
14
|
+
*
|
|
15
|
+
* If the token is an error token, just `start` or `end` can be passed, and the other position will be filled to the same value.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
export function token<
|
|
19
|
+
TValue extends string | undefined,
|
|
20
|
+
TType extends TOKEN_TYPE = TOKEN_TYPE,
|
|
21
|
+
>(
|
|
22
|
+
type: TValue extends undefined ? TType | TType[] : TType,
|
|
23
|
+
value: TValue,
|
|
24
|
+
position: Position | Partial<Position> | EmptyObj = {}
|
|
25
|
+
): TValue extends undefined
|
|
26
|
+
? ErrorToken<TType>
|
|
27
|
+
: ValidToken<TType> {
|
|
28
|
+
position = pos(position, { fill: true })
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
30
|
+
let token: AnyToken<TType>
|
|
31
|
+
if (value !== undefined) {
|
|
32
|
+
token = new ValidToken<TType>({
|
|
33
|
+
type: type as TType,
|
|
34
|
+
value,
|
|
35
|
+
start: position.start!,
|
|
36
|
+
end: position.end!,
|
|
37
|
+
})
|
|
38
|
+
} else {
|
|
39
|
+
token = new ErrorToken<TType>({
|
|
40
|
+
expected: (isArray(type) ? type : [type]) as TType[],
|
|
41
|
+
start: position.start!,
|
|
42
|
+
end: position.end!,
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
return token as any
|
|
46
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type ExtractTokenType, TOKEN_TYPE } from "../../types/ast.js"
|
|
2
|
+
/**
|
|
3
|
+
* Given a the string value of an operator or single delimiter token, returns the corresponding @see ValidToken_TYPE .
|
|
4
|
+
*/
|
|
5
|
+
export function type<T extends string>(
|
|
6
|
+
operatorSymbol: T
|
|
7
|
+
): ExtractTokenType<T> {
|
|
8
|
+
switch (operatorSymbol) {
|
|
9
|
+
case "`": return TOKEN_TYPE.BACKTICK as any
|
|
10
|
+
case `'`: return TOKEN_TYPE.SINGLEQUOTE as any
|
|
11
|
+
case `"`: return TOKEN_TYPE.DOUBLEQUOTE as any
|
|
12
|
+
case `(`: return TOKEN_TYPE.PARENL as any
|
|
13
|
+
case `)`: return TOKEN_TYPE.PARENR as any
|
|
14
|
+
case `[`: return TOKEN_TYPE.BRACKETL as any
|
|
15
|
+
case `]`: return TOKEN_TYPE.BRACKETR as any
|
|
16
|
+
case `/`: return TOKEN_TYPE.REGEX as any
|
|
17
|
+
case `and`:
|
|
18
|
+
case `&&`:
|
|
19
|
+
case `&`:
|
|
20
|
+
return TOKEN_TYPE.AND as any
|
|
21
|
+
case `or`:
|
|
22
|
+
case `||`:
|
|
23
|
+
case `|`:
|
|
24
|
+
return TOKEN_TYPE.OR as any
|
|
25
|
+
case `not`:
|
|
26
|
+
case `!`:
|
|
27
|
+
return TOKEN_TYPE.NOT as any
|
|
28
|
+
default:
|
|
29
|
+
return TOKEN_TYPE.VALUE as any
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { pos } from "./pos.js"
|
|
2
|
+
import { token } from "./token.js"
|
|
3
|
+
|
|
4
|
+
import { type AnyToken, type EmptyObj, type Position, TOKEN_TYPE, type TokenQuoteTypes } from "../../types/ast.js"
|
|
5
|
+
import type { ValidToken } from "../classes/ValidToken.js"
|
|
6
|
+
import { VariableNode } from "../classes/VariableNode.js"
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Creates an @see VariableNode .
|
|
11
|
+
*
|
|
12
|
+
* @param quote Use to add quotes to the variable, usually by using @see delim . If false or undefined, no quotes are added. Otherwise at least `type` must be passed. If one side is defined but not the other, error tokens will be created with the given type.
|
|
13
|
+
*
|
|
14
|
+
* @param position Refers to position of the value (in case it needs to be created) not the node. Quote positions are automatically calculated from this if used. If value is already a token, there's no need to pass a position, it can be extracted from the token.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export function variable(
|
|
18
|
+
prefix: ValidToken<TOKEN_TYPE.VALUE> | undefined,
|
|
19
|
+
value: string | AnyToken<TOKEN_TYPE.VALUE>,
|
|
20
|
+
quote?: { type: TokenQuoteTypes, left?: boolean, right?: boolean, flags?: string },
|
|
21
|
+
position?: Position | EmptyObj
|
|
22
|
+
): VariableNode {
|
|
23
|
+
if (typeof value === "string") {
|
|
24
|
+
value = token(TOKEN_TYPE.VALUE, value, position)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
position = pos(value)
|
|
28
|
+
|
|
29
|
+
const node: Partial<ConstructorParameters<typeof VariableNode>[0]> = {
|
|
30
|
+
value,
|
|
31
|
+
prefix,
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (quote) {
|
|
35
|
+
node.quote = {} as any
|
|
36
|
+
|
|
37
|
+
const quoteLeftPos = position?.start !== undefined
|
|
38
|
+
? pos({ start: position.start }, { fill: true })
|
|
39
|
+
: undefined
|
|
40
|
+
|
|
41
|
+
if (quote.left) {
|
|
42
|
+
if (quoteLeftPos) quoteLeftPos.start -= 1
|
|
43
|
+
node.quote!.left = token(quote.type, quoteFromType(quote.type), quoteLeftPos)
|
|
44
|
+
} else {
|
|
45
|
+
node.quote!.left = token(quote.type, undefined, quoteLeftPos)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const quoteRightPos = position?.end !== undefined
|
|
49
|
+
? pos({ end: position.end }, { fill: true })
|
|
50
|
+
: undefined
|
|
51
|
+
|
|
52
|
+
if (quote.right) {
|
|
53
|
+
if (quoteRightPos) quoteRightPos.end += 1
|
|
54
|
+
node.quote!.right = token(quote.type, quoteFromType(quote.type), quoteRightPos)
|
|
55
|
+
} else {
|
|
56
|
+
node.quote!.right = token(quote.type, undefined, quoteRightPos)
|
|
57
|
+
}
|
|
58
|
+
if (quote.flags) {
|
|
59
|
+
const start = node.quote!.right.end // is always defined if there are flags
|
|
60
|
+
node.quote!.flags = token(TOKEN_TYPE.VALUE, quote.flags, {
|
|
61
|
+
start, end: start + quote.flags?.length,
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
node.start =
|
|
67
|
+
node.prefix?.start ??
|
|
68
|
+
node.quote?.left.start ??
|
|
69
|
+
node.value?.start ??
|
|
70
|
+
node.quote?.right.start
|
|
71
|
+
node.end =
|
|
72
|
+
node.quote?.flags?.end ??
|
|
73
|
+
node.quote?.right.end ??
|
|
74
|
+
node.value?.end ??
|
|
75
|
+
node.quote?.left.end
|
|
76
|
+
|
|
77
|
+
const instance = new VariableNode(node as any)
|
|
78
|
+
return instance
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function quoteFromType(type: TokenQuoteTypes | undefined): string {
|
|
82
|
+
switch (type) {
|
|
83
|
+
case TOKEN_TYPE.BACKTICK: return "`"
|
|
84
|
+
case TOKEN_TYPE.DOUBLEQUOTE: return "\""
|
|
85
|
+
case TOKEN_TYPE.SINGLEQUOTE: return "'"
|
|
86
|
+
case TOKEN_TYPE.REGEX: return "/"
|
|
87
|
+
case undefined: return ""
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ConditionNode } from "./ConditionNode.js"
|
|
2
|
+
import { Node } from "./Node.js"
|
|
3
|
+
import { ValidToken } from "./ValidToken.js"
|
|
4
|
+
import type { VariableNode } from "./VariableNode.js"
|
|
5
|
+
|
|
6
|
+
import { AST_TYPE, type NodeDelimiters, type TOKEN_TYPE } from "../../types/ast.js"
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
export class ArrayNode<
|
|
10
|
+
TValid extends boolean = boolean,
|
|
11
|
+
> extends Node<AST_TYPE.ARRAY> {
|
|
12
|
+
readonly values: VariableNode[]
|
|
13
|
+
|
|
14
|
+
readonly bracket: NodeDelimiters<TOKEN_TYPE.BRACKETL, TOKEN_TYPE.BRACKETR>
|
|
15
|
+
|
|
16
|
+
#parent: any
|
|
17
|
+
|
|
18
|
+
#setParent: boolean = false
|
|
19
|
+
|
|
20
|
+
get parent(): ConditionNode | undefined {
|
|
21
|
+
return this.#parent
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
set parent(value: ConditionNode | undefined) {
|
|
25
|
+
if (this.#setParent) { throw new Error("parent property is readonly") }
|
|
26
|
+
this.#parent = value
|
|
27
|
+
this.#setParent = true
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
constructor({ values, bracket, start, end }: {
|
|
31
|
+
values: ArrayNode<TValid>["values"]
|
|
32
|
+
bracket: ArrayNode<TValid>["bracket"]
|
|
33
|
+
start: number
|
|
34
|
+
end: number
|
|
35
|
+
}) {
|
|
36
|
+
super(AST_TYPE.ARRAY, start, end)
|
|
37
|
+
this.values = values
|
|
38
|
+
this.bracket = bracket
|
|
39
|
+
// @ts-expect-error ignore readonly
|
|
40
|
+
this.valid = (
|
|
41
|
+
this.values.every(val => val.valid) &&
|
|
42
|
+
this.bracket.left instanceof ValidToken &&
|
|
43
|
+
this.bracket.right instanceof ValidToken
|
|
44
|
+
) as TValid
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export class Condition<TOp extends string = string, TValue = any> {
|
|
2
|
+
readonly value: TValue
|
|
3
|
+
|
|
4
|
+
readonly operator?: TOp
|
|
5
|
+
|
|
6
|
+
readonly property: string[]
|
|
7
|
+
|
|
8
|
+
readonly negate: boolean
|
|
9
|
+
|
|
10
|
+
constructor({ property, operator, value, negate }: {
|
|
11
|
+
property: Condition<TOp, TValue>["property"]
|
|
12
|
+
operator: Condition<TOp, TValue>["operator"]
|
|
13
|
+
value: Condition<TOp, TValue>["value"]
|
|
14
|
+
negate: Condition<TOp, TValue>["negate"]
|
|
15
|
+
}) {
|
|
16
|
+
this.value = value
|
|
17
|
+
this.operator = operator
|
|
18
|
+
this.property = property
|
|
19
|
+
this.negate = negate
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|