kriti-lang
Version:
A TypeScript implementation of the Kriti templating language
165 lines (159 loc) • 4.69 kB
TypeScript
interface Position {
line: number;
column: number;
offset: number;
}
interface Token {
type: TokenType;
value: string;
start: Position;
end: Position;
}
declare enum TokenType {
STRING = "STRING",
NUMBER = "NUMBER",
INTEGER = "INTEGER",
BOOLEAN = "BOOLEAN",
NULL = "NULL",
IDENTIFIER = "IDENTIFIER",
IF = "IF",
ELIF = "ELIF",
ELSE = "ELSE",
END = "END",
RANGE = "RANGE",
IN = "IN",
NOT = "NOT",
TRUE = "TRUE",
FALSE = "FALSE",
EQ = "EQ",// ==
NE = "NE",// !=
GT = "GT",// >
LT = "LT",// <
GTE = "GTE",// >=
LTE = "LTE",// <=
AND = "AND",// &&
OR = "OR",// ||
DEFAULT = "DEFAULT",// ??
ASSIGN = "ASSIGN",// :=
COLON = "COLON",// :
DOT = "DOT",// .
COMMA = "COMMA",// ,
QUESTION = "QUESTION",// ?
SQUOTE = "SQUOTE",// '
UNDERSCORE = "UNDERSCORE",// _
LPAREN = "LPAREN",// (
RPAREN = "RPAREN",// )
LBRACE = "LBRACE",// {
RBRACE = "RBRACE",// }
LBRACKET = "LBRACKET",// [
RBRACKET = "RBRACKET",// ]
DQUOTE = "DQUOTE",// "
TEMPLATE_START = "TEMPLATE_START",// {{
TEMPLATE_END = "TEMPLATE_END",// }}
STRING_LITERAL = "STRING_LITERAL",
EOF = "EOF",
NEWLINE = "NEWLINE",
WHITESPACE = "WHITESPACE",
COMMENT = "COMMENT"
}
declare function tokenizeKriti(input: string): Token[];
interface ASTNode {
type: string;
start: Position;
end: Position;
}
interface LiteralNode extends ASTNode {
type: 'Literal';
valueType: 'string' | 'number' | 'integer' | 'boolean' | 'null';
value: string | number | boolean | null;
}
interface IdentifierNode extends ASTNode {
type: 'Identifier';
name: string;
}
interface VariableNode extends ASTNode {
type: 'Variable';
name: string;
}
interface BinaryExpressionNode extends ASTNode {
type: 'BinaryExpression';
operator: '==' | '!=' | '>' | '<' | '>=' | '<=' | '&&' | '||' | 'in' | '??';
left: ExpressionNode;
right: ExpressionNode;
}
interface UnaryExpressionNode extends ASTNode {
type: 'UnaryExpression';
operator: 'not';
operand: ExpressionNode;
}
interface FieldAccessNode extends ASTNode {
type: 'FieldAccess';
object: ExpressionNode;
field: string | ExpressionNode;
computed: boolean;
optional: boolean;
}
interface OptionalChainNode extends ASTNode {
type: 'OptionalChain';
object: ExpressionNode;
chain: Array<{
type: 'field' | 'computed';
value: string | ExpressionNode;
}>;
}
interface FunctionCallNode extends ASTNode {
type: 'FunctionCall';
name: string;
argument: ExpressionNode;
}
interface ArrayNode extends ASTNode {
type: 'Array';
elements: ExpressionNode[];
}
interface ObjectNode extends ASTNode {
type: 'Object';
properties: Array<{
key: ExpressionNode;
value: ExpressionNode;
}>;
}
interface StringTemplateNode extends ASTNode {
type: 'StringTemplate';
parts: Array<LiteralNode | ExpressionNode>;
}
interface ConditionalNode extends ASTNode {
type: 'Conditional';
condition: ExpressionNode;
thenExpression: ExpressionNode;
elifs: Array<{
condition: ExpressionNode;
expression: ExpressionNode;
}>;
elseExpression: ExpressionNode;
}
interface RangeNode extends ASTNode {
type: 'Range';
index: string | null;
variable: string;
iterable: ExpressionNode;
body: ExpressionNode;
}
interface TemplateExpressionNode extends ASTNode {
type: 'TemplateExpression';
expression: ExpressionNode;
}
type ExpressionNode = LiteralNode | IdentifierNode | VariableNode | BinaryExpressionNode | UnaryExpressionNode | FieldAccessNode | OptionalChainNode | FunctionCallNode | ArrayNode | ObjectNode | StringTemplateNode | ConditionalNode | RangeNode | TemplateExpressionNode;
type RuntimeValue = string | number | boolean | null | RuntimeValue[] | RuntimeObject | undefined;
interface RuntimeObject {
[key: string]: RuntimeValue;
}
interface EvaluationContext {
variables: Map<string, RuntimeValue>;
functions: Map<string, CustomFunction>;
parent?: EvaluationContext;
}
type CustomFunction = (arg: RuntimeValue, context: EvaluationContext) => RuntimeValue;
declare function evaluateKriti(node: ExpressionNode, variables?: RuntimeObject, customFunctions?: Map<string, CustomFunction>): RuntimeValue;
declare function parseKriti(tokens: Token[]): ExpressionNode;
declare function evaluate(input: string, variables?: RuntimeObject, customFunctions?: Map<string, CustomFunction>): RuntimeValue;
export { evaluate, evaluateKriti as evaluateAST, parseKriti as parseTokens, tokenizeKriti as tokenize };