getValue functions

This commit is contained in:
4eb0da
2023-03-06 13:09:09 +03:00
parent 40d971a798
commit ba137d195e
11 changed files with 784 additions and 76 deletions
+2 -2
View File
@@ -8,7 +8,7 @@ import {
TemplateLiteral,
UnaryExpression, Variable
} from './ast';
import { findBestMatchedFunc, Func, funcByArgs, funcs } from './funcs/funcs';
import { findBestMatchedFunc, Func, funcByArgs } from './funcs/funcs';
import { evalError, roundInteger, typeToString, valToInternal, valToPreview, valToString } from './utils';
import { BOOLEAN, DATETIME, INTEGER, NUMBER, STRING } from './const';
import { register } from './funcs';
@@ -384,7 +384,7 @@ function evalCallExpression(vars: VariablesMap, expr: CallExpression): EvalValue
}
try {
return func.cb(...args);
return func.cb(vars, ...args);
} catch (err: any) {
const prefix = `${funcName}(${argsToStr(args)})`;
evalError(prefix, err.message);
@@ -1,11 +1,14 @@
import type { ColorValue, EvalValue, NumberValue, StringValue } from '../eval';
import type { ParsedColor } from '../../utils/correctColor';
import type { VariablesMap } from '../eval';
import { registerFunc } from './funcs';
import { COLOR, NUMBER, STRING } from '../const';
import { ParsedColor } from '../../utils/correctColor';
import { safeConvertColor, stringifyColor } from '../utils';
function colorGetter(field: keyof ParsedColor): (color: StringValue | ColorValue) => EvalValue {
return color => {
function colorGetter(
field: keyof ParsedColor
): (_vars: VariablesMap, color: StringValue | ColorValue) => EvalValue {
return (_vars, color) => {
const parsed = safeConvertColor(color.value);
return {
@@ -15,8 +18,10 @@ function colorGetter(field: keyof ParsedColor): (color: StringValue | ColorValue
};
}
function colorSetter(field: keyof ParsedColor): (color: StringValue | ColorValue, val: NumberValue) => EvalValue {
return (color, val) => {
function colorSetter(
field: keyof ParsedColor
): (_vars: VariablesMap, color: StringValue | ColorValue, val: NumberValue) => EvalValue {
return (_vars, color, val) => {
const parsed = safeConvertColor(color.value);
parsed[field] = val.value * 255;
@@ -38,7 +43,7 @@ const setColorRed = colorSetter('r');
const setColorGreen = colorSetter('g');
const setColorBlue = colorSetter('b');
function rgb(red: NumberValue, green: NumberValue, blue: NumberValue): EvalValue {
function rgb(_vars: VariablesMap, red: NumberValue, green: NumberValue, blue: NumberValue): EvalValue {
const parsed: ParsedColor = {
a: 255,
r: red.value * 255,
@@ -52,7 +57,13 @@ function rgb(red: NumberValue, green: NumberValue, blue: NumberValue): EvalValue
};
}
function argb(alpha: NumberValue, red: NumberValue, green: NumberValue, blue: NumberValue): EvalValue {
function argb(
_vars: VariablesMap,
alpha: NumberValue,
red: NumberValue,
green: NumberValue,
blue: NumberValue
): EvalValue {
const parsed: ParsedColor = {
a: alpha.value * 255,
r: red.value * 255,
@@ -1,9 +1,19 @@
import type { DatetimeValue, EvalValue, IntegerValue } from '../eval';
import type { VariablesMap } from '../eval';
import { registerFunc } from './funcs';
import { DATETIME, INTEGER } from '../const';
import { valToString } from '../utils';
function parseUnixTime(arg: IntegerValue): EvalValue {
function getMaxDate(date: Date): number {
const copy = new Date(date);
copy.setMonth(copy.getMonth() + 1);
copy.setDate(0);
return copy.getDate();
}
function parseUnixTime(_vars: VariablesMap, arg: IntegerValue): EvalValue {
return {
type: DATETIME,
value: new Date(arg.value * 1000)
@@ -17,14 +27,14 @@ function nowLocal(): EvalValue {
};
}
function addMillis(datetime: DatetimeValue, milliseconds: IntegerValue): EvalValue {
function addMillis(_vars: VariablesMap, datetime: DatetimeValue, milliseconds: IntegerValue): EvalValue {
return {
type: DATETIME,
value: new Date(datetime.value.getTime() + milliseconds.value)
};
}
function setYear(datetime: DatetimeValue, year: IntegerValue): EvalValue {
function setYear(_vars: VariablesMap, datetime: DatetimeValue, year: IntegerValue): EvalValue {
const copy = new Date(datetime.value);
copy.setFullYear(year.value);
@@ -35,7 +45,7 @@ function setYear(datetime: DatetimeValue, year: IntegerValue): EvalValue {
};
}
function setMonth(datetime: DatetimeValue, month: IntegerValue): EvalValue {
function setMonth(_vars: VariablesMap, datetime: DatetimeValue, month: IntegerValue): EvalValue {
if (month.value < 1 || month.value > 12) {
throw new Error(`Expecting month in [1..12], instead got ${month.value}.`);
}
@@ -50,16 +60,7 @@ function setMonth(datetime: DatetimeValue, month: IntegerValue): EvalValue {
};
}
function getMaxDate(date: Date): number {
const copy = new Date(date);
copy.setMonth(copy.getMonth() + 1);
copy.setDate(0);
return copy.getDate();
}
function setDay(datetime: DatetimeValue, day: IntegerValue): EvalValue {
function setDay(_vars: VariablesMap, datetime: DatetimeValue, day: IntegerValue): EvalValue {
const copy = new Date(datetime.value);
if (day.value <= 0 && day.value !== -1 || day.value > getMaxDate(copy)) {
@@ -74,7 +75,7 @@ function setDay(datetime: DatetimeValue, day: IntegerValue): EvalValue {
};
}
function setHours(datetime: DatetimeValue, hours: IntegerValue): EvalValue {
function setHours(_vars: VariablesMap, datetime: DatetimeValue, hours: IntegerValue): EvalValue {
if (hours.value < 0 || hours.value > 23) {
throw new Error(`Expecting hours in [0..23], instead got ${hours.value}.`);
}
@@ -89,7 +90,7 @@ function setHours(datetime: DatetimeValue, hours: IntegerValue): EvalValue {
};
}
function setMinutes(datetime: DatetimeValue, minutes: IntegerValue): EvalValue {
function setMinutes(_vars: VariablesMap, datetime: DatetimeValue, minutes: IntegerValue): EvalValue {
if (minutes.value < 0 || minutes.value > 59) {
throw new Error(`Expecting minutes in [0..59], instead got ${minutes.value}.`);
}
@@ -104,7 +105,7 @@ function setMinutes(datetime: DatetimeValue, minutes: IntegerValue): EvalValue {
};
}
function setSeconds(datetime: DatetimeValue, seconds: IntegerValue): EvalValue {
function setSeconds(_vars: VariablesMap, datetime: DatetimeValue, seconds: IntegerValue): EvalValue {
if (seconds.value < 0 || seconds.value > 59) {
throw new Error(`Expecting seconds in [0..59], instead got ${seconds.value}.`);
}
@@ -119,7 +120,7 @@ function setSeconds(datetime: DatetimeValue, seconds: IntegerValue): EvalValue {
};
}
function setMillis(datetime: DatetimeValue, millis: IntegerValue): EvalValue {
function setMillis(_vars: VariablesMap, datetime: DatetimeValue, millis: IntegerValue): EvalValue {
if (millis.value < 0 || millis.value > 999) {
throw new Error(`Expecting millis in [0..999], instead got ${millis.value}.`);
}
@@ -1,4 +1,5 @@
import type { EvalTypes, EvalValue } from '../eval';
import type { VariablesMap } from '../eval';
export type FuncArg = EvalTypes | {
type: EvalTypes;
@@ -7,7 +8,7 @@ export type FuncArg = EvalTypes | {
export interface Func {
args: FuncArg[];
cb(...args: EvalValue[]): EvalValue;
cb(vars: VariablesMap, ...args: EvalValue[]): EvalValue;
}
export const funcs: Map<string, Func[]> = new Map();
@@ -30,7 +31,7 @@ type FuncMatchError = {
};
// no args
export function registerFunc(name: string, args: [], cb: () => EvalValue): void;
export function registerFunc(name: string, args: [], cb: (vars?: VariablesMap) => EvalValue): void;
// one specific arg
export function registerFunc<
A0 extends EvalTypes
@@ -38,6 +39,7 @@ export function registerFunc<
name: string,
args: [A0],
cb: (
vars: VariablesMap,
arg0: Extract<EvalValue, { type: A0 }>
) => EvalValue
): void;
@@ -49,6 +51,7 @@ export function registerFunc<
name: string,
args: [A0, A1],
cb: (
vars: VariablesMap,
arg0: Extract<EvalValue, { type: A0 }>,
arg1: Extract<EvalValue, { type: A1 }>
) => EvalValue
@@ -62,15 +65,24 @@ export function registerFunc<
name: string,
args: [A0, A1, A2],
cb: (
vars: VariablesMap,
arg0: Extract<EvalValue, { type: A0 }>,
arg1: Extract<EvalValue, { type: A1 }>,
arg2: Extract<EvalValue, { type: A2 }>
) => EvalValue
): void;
// any args
export function registerFunc(name: string, args: FuncArg[], cb: (...args: any[]) => EvalValue): void;
export function registerFunc(
name: string,
args: FuncArg[],
cb: (vars: VariablesMap, ...args: any[]) => EvalValue
): void;
export function registerFunc(name: string, args: FuncArg[], cb: (...args: EvalValue[]) => EvalValue): void {
export function registerFunc(
name: string,
args: FuncArg[],
cb: (vars: VariablesMap, ...args: EvalValue[]) => EvalValue
): void {
const desc: Func = {
args,
cb
@@ -1,4 +1,5 @@
import type { EvalValue, IntegerValue } from '../eval';
import type { VariablesMap } from '../eval';
import { registerFunc } from './funcs';
import { INTEGER } from '../const';
@@ -27,35 +28,35 @@ const HOURS_IN_DAY = 24;
const MS_IN_DAY = 1000 * 60 * 60 * 24;
const MS_IN_WEEK = 1000 * 60 * 60 * 24 * 7;
function getIntervalSeconds(milliseconds: IntegerValue): EvalValue {
function getIntervalSeconds(_vars: VariablesMap, milliseconds: IntegerValue): EvalValue {
return getDuration(milliseconds, MS_IN_SECOND, SECONDS_IN_MINUTE);
}
function getIntervalTotalSeconds(milliseconds: IntegerValue): EvalValue {
function getIntervalTotalSeconds(_vars: VariablesMap, milliseconds: IntegerValue): EvalValue {
return getDuration(milliseconds, MS_IN_SECOND);
}
function getIntervalMinutes(milliseconds: IntegerValue): EvalValue {
function getIntervalMinutes(_vars: VariablesMap, milliseconds: IntegerValue): EvalValue {
return getDuration(milliseconds, MS_IN_MINUTE, MINUTES_IN_HOUR);
}
function getIntervalTotalMinutes(milliseconds: IntegerValue): EvalValue {
function getIntervalTotalMinutes(_vars: VariablesMap, milliseconds: IntegerValue): EvalValue {
return getDuration(milliseconds, MS_IN_MINUTE);
}
function getIntervalHours(milliseconds: IntegerValue): EvalValue {
function getIntervalHours(_vars: VariablesMap, milliseconds: IntegerValue): EvalValue {
return getDuration(milliseconds, MS_IN_HOUR, HOURS_IN_DAY);
}
function getIntervalTotalHours(milliseconds: IntegerValue): EvalValue {
function getIntervalTotalHours(_vars: VariablesMap, milliseconds: IntegerValue): EvalValue {
return getDuration(milliseconds, MS_IN_HOUR);
}
function getIntervalTotalDays(milliseconds: IntegerValue): EvalValue {
function getIntervalTotalDays(_vars: VariablesMap, milliseconds: IntegerValue): EvalValue {
return getDuration(milliseconds, MS_IN_DAY);
}
function getIntervalTotalWeeks(milliseconds: IntegerValue): EvalValue {
function getIntervalTotalWeeks(_vars: VariablesMap, milliseconds: IntegerValue): EvalValue {
return getDuration(milliseconds, MS_IN_WEEK);
}
+14 -14
View File
@@ -1,9 +1,10 @@
import type { EvalValue, IntegerValue, NumberValue } from '../eval';
import type { VariablesMap } from '../eval';
import { registerFunc } from './funcs';
import { INTEGER, MAX_INT, MAX_NUMBER, MIN_INT, MIN_NUMBER, NUMBER } from '../const';
import { checkIntegerOverflow, roundInteger } from '../utils';
function div<T extends IntegerValue | NumberValue>(arg0: T, arg1: T): EvalValue {
function div<T extends IntegerValue | NumberValue>(_vars: VariablesMap, arg0: T, arg1: T): EvalValue {
if (arg1.value === 0) {
throw new Error('Division by zero is not supported.');
}
@@ -19,7 +20,7 @@ function div<T extends IntegerValue | NumberValue>(arg0: T, arg1: T): EvalValue
};
}
function mod<T extends IntegerValue | NumberValue>(arg0: T, arg1: T): EvalValue {
function mod<T extends IntegerValue | NumberValue>(_vars: VariablesMap, arg0: T, arg1: T): EvalValue {
if (arg1.value === 0) {
throw new Error('Division by zero is not supported.');
}
@@ -35,7 +36,7 @@ function mod<T extends IntegerValue | NumberValue>(arg0: T, arg1: T): EvalValue
};
}
function mul<T extends IntegerValue | NumberValue>(...args: T[]): EvalValue {
function mul<T extends IntegerValue | NumberValue>(_vars: VariablesMap, ...args: T[]): EvalValue {
let res = args.length ? args[0].value : 0;
for (let i = 1; i < args.length; ++i) {
res *= args[i].value;
@@ -50,7 +51,7 @@ function mul<T extends IntegerValue | NumberValue>(...args: T[]): EvalValue {
};
}
function sub<T extends IntegerValue | NumberValue>(...args: T[]): EvalValue {
function sub<T extends IntegerValue | NumberValue>(_vars: VariablesMap, ...args: T[]): EvalValue {
let res = args.length ? args[0].value : 0;
for (let i = 1; i < args.length; ++i) {
res -= args[i].value;
@@ -65,7 +66,7 @@ function sub<T extends IntegerValue | NumberValue>(...args: T[]): EvalValue {
};
}
function sum<T extends IntegerValue | NumberValue>(...args: T[]): EvalValue {
function sum<T extends IntegerValue | NumberValue>(_vars: VariablesMap, ...args: T[]): EvalValue {
let res = 0;
for (let i = 0; i < args.length; ++i) {
res += args[i].value;
@@ -80,7 +81,7 @@ function sum<T extends IntegerValue | NumberValue>(...args: T[]): EvalValue {
};
}
function abs(arg: IntegerValue | NumberValue): EvalValue {
function abs(_vars: VariablesMap, arg: IntegerValue | NumberValue): EvalValue {
const res = Math.abs(arg.value);
if (arg.type === INTEGER) {
@@ -93,7 +94,7 @@ function abs(arg: IntegerValue | NumberValue): EvalValue {
};
}
function max<T extends IntegerValue | NumberValue>(...args: T[]): EvalValue {
function max<T extends IntegerValue | NumberValue>(_vars: VariablesMap, ...args: T[]): EvalValue {
if (!args.length) {
throw new Error('Non empty argument list is required for function \'max\'.');
}
@@ -104,7 +105,7 @@ function max<T extends IntegerValue | NumberValue>(...args: T[]): EvalValue {
};
}
function min<T extends IntegerValue | NumberValue>(...args: T[]): EvalValue {
function min<T extends IntegerValue | NumberValue>(_vars: VariablesMap, ...args: T[]): EvalValue {
if (!args.length) {
throw new Error('Non empty argument list is required for function \'min\'.');
}
@@ -143,10 +144,9 @@ function minInteger(): EvalValue {
};
}
function round(arg: NumberValue): EvalValue {
function round(_vars: VariablesMap, arg: NumberValue): EvalValue {
const sign = Math.sign(arg.value);
return {
type: NUMBER,
// js treats Math.round(-0.5) as 0, which is different to other platforms
@@ -154,28 +154,28 @@ function round(arg: NumberValue): EvalValue {
};
}
function floor(arg: NumberValue): EvalValue {
function floor(_vars: VariablesMap, arg: NumberValue): EvalValue {
return {
type: NUMBER,
value: Math.floor(arg.value)
};
}
function ceil(arg: NumberValue): EvalValue {
function ceil(_vars: VariablesMap, arg: NumberValue): EvalValue {
return {
type: NUMBER,
value: Math.ceil(arg.value)
};
}
function signum(arg: IntegerValue | NumberValue): EvalValue {
function signum(_vars: VariablesMap, arg: IntegerValue | NumberValue): EvalValue {
return {
type: arg.type,
value: Math.sign(arg.value)
};
}
function copySign<T extends IntegerValue | NumberValue>(arg0: T, arg1: T): EvalValue {
function copySign<T extends IntegerValue | NumberValue>(_vars: VariablesMap, arg0: T, arg1: T): EvalValue {
let res: number;
if (arg1.value === 0 && arg0.type === INTEGER) {
+74 -10
View File
@@ -1,9 +1,14 @@
import type { BooleanValue, ColorValue, EvalValue, IntegerValue, NumberValue, StringValue, UrlValue } from '../eval';
import type { VariablesMap } from '../eval';
import type { VariableType, VariableValue } from '../variable';
import { registerFunc } from './funcs';
import { BOOLEAN, COLOR, INTEGER, MAX_INT, MIN_INT, NUMBER, STRING, URL } from '../const';
import { valToString } from '../utils';
import { transformColorValue, valToString } from '../utils';
function toString(arg: IntegerValue | NumberValue | BooleanValue | ColorValue | UrlValue): EvalValue {
function toString(
_vars: VariablesMap,
arg: IntegerValue | NumberValue | BooleanValue | ColorValue | UrlValue
): EvalValue {
return {
type: STRING,
value: valToString(arg)
@@ -11,7 +16,7 @@ function toString(arg: IntegerValue | NumberValue | BooleanValue | ColorValue |
}
function toNumber(arg: IntegerValue | StringValue): EvalValue {
function toNumber(_vars: VariablesMap, arg: IntegerValue | StringValue): EvalValue {
const num = Number(arg.value);
if (isNaN(num) || !Number.isFinite(num)) {
@@ -25,7 +30,7 @@ function toNumber(arg: IntegerValue | StringValue): EvalValue {
}
function toIntegerNumber(arg: NumberValue): EvalValue {
function toIntegerNumber(_vars: VariablesMap, arg: NumberValue): EvalValue {
if (arg.value > MAX_INT || arg.value < MIN_INT) {
throw new Error('Unable to convert value to Integer.');
}
@@ -38,7 +43,7 @@ function toIntegerNumber(arg: NumberValue): EvalValue {
};
}
function toIntegerString(arg: StringValue): EvalValue {
function toIntegerString(_vars: VariablesMap, arg: StringValue): EvalValue {
const num = Number(arg.value);
if (isNaN(num) || num % 1 !== 0 || num > MAX_INT || num < MIN_INT) {
@@ -51,7 +56,7 @@ function toIntegerString(arg: StringValue): EvalValue {
};
}
function toIntegerBoolean(arg: BooleanValue): EvalValue {
function toIntegerBoolean(_vars: VariablesMap, arg: BooleanValue): EvalValue {
return {
type: INTEGER,
value: arg.value ? 1 : 0
@@ -59,7 +64,7 @@ function toIntegerBoolean(arg: BooleanValue): EvalValue {
}
function toBooleanInteger(arg: IntegerValue): EvalValue {
function toBooleanInteger(_vars: VariablesMap, arg: IntegerValue): EvalValue {
if (arg.value !== 1 && arg.value !== 0) {
throw new Error('Unable to convert value to Boolean.');
}
@@ -70,7 +75,7 @@ function toBooleanInteger(arg: IntegerValue): EvalValue {
};
}
function toBooleanString(arg: StringValue): EvalValue {
function toBooleanString(_vars: VariablesMap, arg: StringValue): EvalValue {
if (arg.value !== 'true' && arg.value !== 'false') {
throw new Error('Unable to convert value to Boolean.');
}
@@ -81,7 +86,7 @@ function toBooleanString(arg: StringValue): EvalValue {
};
}
function encodeUri(str: StringValue): EvalValue {
function encodeUri(_vars: VariablesMap, str: StringValue): EvalValue {
try {
return {
type: STRING,
@@ -92,7 +97,7 @@ function encodeUri(str: StringValue): EvalValue {
}
}
function decodeUri(str: StringValue): EvalValue {
function decodeUri(_vars: VariablesMap, str: StringValue): EvalValue {
try {
return {
type: STRING,
@@ -103,6 +108,56 @@ function decodeUri(str: StringValue): EvalValue {
}
}
function getValueForced(
vars: VariablesMap,
varName: StringValue,
fallback: IntegerValue | NumberValue | StringValue | BooleanValue | UrlValue | ColorValue,
type: VariableType
): EvalValue {
const variable = vars.get(varName.value);
let value: VariableValue;
if (variable && variable.getType() === type) {
value = variable.getValue();
} else {
value = fallback.value;
}
if (type === 'color') {
value = transformColorValue(value as string);
}
return {
type,
// value is synced with type by params
value: value as any
};
}
function getValue(
vars: VariablesMap,
varName: StringValue,
fallback: IntegerValue | NumberValue | StringValue | BooleanValue | UrlValue | ColorValue
): EvalValue {
return getValueForced(vars, varName, fallback, fallback.type);
}
function getColorValue(
vars: VariablesMap,
varName: StringValue,
fallback: IntegerValue | NumberValue | StringValue | BooleanValue | UrlValue | ColorValue
) {
return getValueForced(vars, varName, fallback, 'color');
}
function getUrlValue(
vars: VariablesMap,
varName: StringValue,
fallback: IntegerValue | NumberValue | StringValue | BooleanValue | UrlValue | ColorValue
) {
return getValueForced(vars, varName, fallback, 'url');
}
export function registerStd(): void {
registerFunc('toString', [INTEGER], toString);
registerFunc('toString', [NUMBER], toString);
@@ -122,4 +177,13 @@ export function registerStd(): void {
registerFunc('encodeUri', [STRING], encodeUri);
registerFunc('decodeUri', [STRING], decodeUri);
registerFunc('getIntegerValue', [STRING, INTEGER], getValue);
registerFunc('getNumberValue', [STRING, NUMBER], getValue);
registerFunc('getBooleanValue', [STRING, BOOLEAN], getValue);
registerFunc('getStringValue', [STRING, STRING], getValue);
registerFunc('getColorValue', [STRING, COLOR], getColorValue);
registerFunc('getColorValue', [STRING, STRING], getColorValue);
registerFunc('getUrlValue', [STRING, URL], getUrlValue);
registerFunc('getUrlValue', [STRING, STRING], getUrlValue);
}
@@ -1,24 +1,25 @@
import type { EvalValue, IntegerValue, StringValue } from '../eval';
import type { VariablesMap } from '../eval';
import { registerFunc } from './funcs';
import { BOOLEAN, INTEGER, STRING } from '../const';
import { escapeRegExp } from '../../utils/escapeRegExp';
import { valToString } from '../utils';
function len(arg: StringValue): EvalValue {
function len(_vars: VariablesMap, arg: StringValue): EvalValue {
return {
type: INTEGER,
value: arg.value.length
};
}
function contains(wholeStr: StringValue, partStr: StringValue): EvalValue {
function contains(_vars: VariablesMap, wholeStr: StringValue, partStr: StringValue): EvalValue {
return {
type: BOOLEAN,
value: wholeStr.value.includes(partStr.value) ? 1 : 0
};
}
function substring(str: StringValue, start: IntegerValue, end: IntegerValue): EvalValue {
function substring(_vars: VariablesMap, str: StringValue, start: IntegerValue, end: IntegerValue): EvalValue {
if (end.value < start.value) {
throw new Error('Indexes should be in ascending order.');
}
@@ -36,7 +37,7 @@ function substring(str: StringValue, start: IntegerValue, end: IntegerValue): Ev
};
}
function replaceAll(str: StringValue, what: StringValue, replacer: StringValue): EvalValue {
function replaceAll(_vars: VariablesMap, str: StringValue, what: StringValue, replacer: StringValue): EvalValue {
let res: string;
if (what.value) {
@@ -52,49 +53,49 @@ function replaceAll(str: StringValue, what: StringValue, replacer: StringValue):
};
}
function index(str: StringValue, what: StringValue): EvalValue {
function index(_vars: VariablesMap, str: StringValue, what: StringValue): EvalValue {
return {
type: INTEGER,
value: str.value.indexOf(what.value)
};
}
function lastIndex(str: StringValue, what: StringValue): EvalValue {
function lastIndex(_vars: VariablesMap, str: StringValue, what: StringValue): EvalValue {
return {
type: INTEGER,
value: str.value.lastIndexOf(what.value)
};
}
function trim(str: StringValue): EvalValue {
function trim(_vars: VariablesMap, str: StringValue): EvalValue {
return {
type: STRING,
value: str.value.trim()
};
}
function trimLeft(str: StringValue): EvalValue {
function trimLeft(_vars: VariablesMap, str: StringValue): EvalValue {
return {
type: STRING,
value: str.value.replace(/^\s+/, '')
};
}
function trimRight(str: StringValue): EvalValue {
function trimRight(_vars: VariablesMap, str: StringValue): EvalValue {
return {
type: STRING,
value: str.value.replace(/\s+$/, '')
};
}
function toUpperCase(str: StringValue): EvalValue {
function toUpperCase(_vars: VariablesMap, str: StringValue): EvalValue {
return {
type: STRING,
value: str.value.toUpperCase()
};
}
function toLowerCase(str: StringValue): EvalValue {
function toLowerCase(_vars: VariablesMap, str: StringValue): EvalValue {
return {
type: STRING,
value: str.value.toLowerCase()
@@ -119,7 +120,12 @@ function calcPad(val: StringValue | IntegerValue, len: IntegerValue, pad: String
return part;
}
function padStart(val: StringValue | IntegerValue, len: IntegerValue, pad: StringValue): EvalValue {
function padStart(
_vars: VariablesMap,
val: StringValue | IntegerValue,
len: IntegerValue,
pad: StringValue
): EvalValue {
const prefix = calcPad(val, len, pad);
return {
@@ -128,7 +134,12 @@ function padStart(val: StringValue | IntegerValue, len: IntegerValue, pad: Strin
};
}
function padEnd(val: StringValue | IntegerValue, len: IntegerValue, pad: StringValue): EvalValue {
function padEnd(
_vars: VariablesMap,
val: StringValue | IntegerValue,
len: IntegerValue,
pad: StringValue
): EvalValue {
const suffix = calcPad(val, len, pad);
return {
@@ -141,3 +141,7 @@ export function stringifyColor(color: ParsedColor): string {
return padLeft(Math.round(it).toString(16), 2);
}).join('').toUpperCase()}`;
}
export function transformColorValue(color: string): string {
return stringifyColor(safeConvertColor(color));
}
@@ -155,6 +155,142 @@
],
"result_type": "string",
"platforms": ["ios", "web"]
},
{
"name": "getIntegerValue(string, integer) integer",
"function_name": "getIntegerValue",
"doc": "Returns the value of a variable by its name. If the variable doesn't exist or has incorrect type, the default value would be returned.",
"arguments": [
{
"type": "string",
"doc": "Variable name."
},
{
"type": "integer",
"doc": "Fallback value."
}
],
"result_type": "integer",
"platforms": ["web"]
},
{
"name": "getNumberValue(string, number) number",
"function_name": "getNumberValue",
"doc": "Returns the value of a variable by its name. If the variable doesn't exist or has incorrect type, the default value would be returned.",
"arguments": [
{
"type": "string",
"doc": "Variable name."
},
{
"type": "number",
"doc": "Fallback value."
}
],
"result_type": "number",
"platforms": ["web"]
},
{
"name": "getStringValue(string, string) string",
"function_name": "getStringValue",
"doc": "Returns the value of a variable by its name. If the variable doesn't exist or has incorrect type, the default value would be returned.",
"arguments": [
{
"type": "string",
"doc": "Variable name."
},
{
"type": "string",
"doc": "Fallback value."
}
],
"result_type": "string",
"platforms": ["web"]
},
{
"name": "getUrlValue(string, url) url",
"function_name": "getUrlValue",
"doc": "Returns the value of a variable by its name. If the variable doesn't exist or has incorrect type, the default value would be returned.",
"arguments": [
{
"type": "string",
"doc": "Variable name."
},
{
"type": "url",
"doc": "Fallback value."
}
],
"result_type": "url",
"platforms": ["web"]
},
{
"name": "getUrlValue(string, string) url",
"function_name": "getUrlValue",
"doc": "Returns the value of a variable by its name. If the variable doesn't exist or has incorrect type, the default value would be returned.",
"arguments": [
{
"type": "string",
"doc": "Variable name."
},
{
"type": "string",
"doc": "Fallback value."
}
],
"result_type": "url",
"platforms": ["web"]
},
{
"name": "getColorValue(string, color) color",
"function_name": "getColorValue",
"doc": "Returns the value of a variable by its name. If the variable doesn't exist or has incorrect type, the default value would be returned.",
"arguments": [
{
"type": "string",
"doc": "Variable name."
},
{
"type": "color",
"doc": "Fallback value."
}
],
"result_type": "color",
"platforms": ["web"]
},
{
"name": "getColorValue(string, string) color",
"function_name": "getColorValue",
"doc": "Returns the value of a variable by its name. If the variable doesn't exist or has incorrect type, the default value would be returned.",
"arguments": [
{
"type": "string",
"doc": "Variable name."
},
{
"type": "string",
"doc": "Fallback value."
}
],
"result_type": "color",
"platforms": ["web"]
},
{
"name": "getBooleanValue(string, boolean) boolean",
"function_name": "getBooleanValue",
"doc": "Returns the value of a variable by its name. If the variable doesn't exist or has incorrect type, the default value would be returned.",
"arguments": [
{
"type": "string",
"doc": "Variable name."
},
{
"type": "boolean",
"doc": "Fallback value."
}
],
"result_type": "boolean",
"platforms": ["web"]
}
]
}
@@ -0,0 +1,468 @@
{
"cases": [
{
"name": "getIntegerValue(correctIntVar, fallback) => intVal",
"expression": "@{getIntegerValue('abc', 456)}",
"expected": {
"type": "integer",
"value": 123
},
"variables": [
{
"type": "integer",
"name": "abc",
"value": 123
}
],
"platforms": [
"web"
]
},
{
"name": "getIntegerValue(incorrectIntVar, fallback) => intVal",
"expression": "@{getIntegerValue('abc', 456)}",
"expected": {
"type": "integer",
"value": 456
},
"variables": [
{
"type": "number",
"name": "abc",
"value": 123.0
}
],
"platforms": [
"web"
]
},
{
"name": "getIntegerValue(nonexistentIntVar, fallback) => intVal",
"expression": "@{getIntegerValue('abc', 456)}",
"expected": {
"type": "integer",
"value": 456
},
"variables": [],
"platforms": [
"web"
]
},
{
"name": "getNumberValue(correctNumberVar, fallback) => numberVal",
"expression": "@{getNumberValue('abc', 456.0)}",
"expected": {
"type": "number",
"value": 123.0
},
"variables": [
{
"type": "number",
"name": "abc",
"value": 123.0
}
],
"platforms": [
"web"
]
},
{
"name": "getNumberValue(incorrectNumberVar, fallback) => numberVal",
"expression": "@{getNumberValue('abc', 456.0)}",
"expected": {
"type": "number",
"value": 456.0
},
"variables": [
{
"type": "integer",
"name": "abc",
"value": 123
}
],
"platforms": [
"web"
]
},
{
"name": "getNumberValue(nonexistentNumberVar, fallback) => numberVal",
"expression": "@{getNumberValue('abc', 456.0)}",
"expected": {
"type": "number",
"value": 456.0
},
"variables": [],
"platforms": [
"web"
]
},
{
"name": "getBooleanValue(correctBooleanVar, fallback) => booleanVal",
"expression": "@{getBooleanValue('abc', false)}",
"expected": {
"type": "boolean",
"value": true
},
"variables": [
{
"type": "boolean",
"name": "abc",
"value": true
}
],
"platforms": [
"web"
]
},
{
"name": "getBooleanValue(incorrectBooleanVar, fallback) => booleanVal",
"expression": "@{getBooleanValue('abc', false)}",
"expected": {
"type": "boolean",
"value": false
},
"variables": [
{
"type": "integer",
"name": "abc",
"value": 123
}
],
"platforms": [
"web"
]
},
{
"name": "getBooleanValue(nonexistentBooleanVar, fallback) => booleanVal",
"expression": "@{getBooleanValue('abc', false)}",
"expected": {
"type": "boolean",
"value": false
},
"variables": [],
"platforms": [
"web"
]
},
{
"name": "getStringValue(correctStringVar, fallback) => stringVal",
"expression": "@{getStringValue('abc', 'b')}",
"expected": {
"type": "string",
"value": "a"
},
"variables": [
{
"type": "string",
"name": "abc",
"value": "a"
}
],
"platforms": [
"web"
]
},
{
"name": "getStringValue(incorrectStringVar, fallback) => stringVal",
"expression": "@{getStringValue('abc', 'b')}",
"expected": {
"type": "string",
"value": "b"
},
"variables": [
{
"type": "integer",
"name": "abc",
"value": 123
}
],
"platforms": [
"web"
]
},
{
"name": "getStringValue(nonexistentStringVar, fallback) => stringVal",
"expression": "@{getStringValue('abc', 'b')}",
"expected": {
"type": "string",
"value": "b"
},
"variables": [],
"platforms": [
"web"
]
},
{
"name": "getColorValue(correctColorVar, fallback) => colorVal",
"expression": "@{getColorValue('abc', fallback)}",
"expected": {
"type": "color",
"value": "#FF000000"
},
"variables": [
{
"type": "color",
"name": "abc",
"value": "#FF000000"
},
{
"type": "color",
"name": "fallback",
"value": "#FFFFFFFF"
}
],
"platforms": [
"web"
]
},
{
"name": "getColorValue(incorrectColorVar, fallback) => colorVal",
"expression": "@{getColorValue('abc', fallback)}",
"expected": {
"type": "color",
"value": "#FFFFFFFF"
},
"variables": [
{
"type": "integer",
"name": "abc",
"value": 123
},
{
"type": "color",
"name": "fallback",
"value": "#FFFFFFFF"
}
],
"platforms": [
"web"
]
},
{
"name": "getColorValue(nonexistentColorVar, fallback) => colorVal",
"expression": "@{getColorValue('abc', fallback)}",
"expected": {
"type": "color",
"value": "#FFFFFFFF"
},
"variables": [
{
"type": "color",
"name": "fallback",
"value": "#FFFFFFFF"
}
],
"platforms": [
"web"
]
},
{
"name": "getColorValue(correctColorVar, fallback) => colorVal",
"expression": "@{getColorValue('abc', '#FFFFFFFF')}",
"expected": {
"type": "color",
"value": "#FF000000"
},
"variables": [
{
"type": "color",
"name": "abc",
"value": "#FF000000"
}
],
"platforms": [
"web"
]
},
{
"name": "getColorValue(incorrectColorVar, fallback) => colorVal",
"expression": "@{getColorValue('abc', '#FFFFFFFF')}",
"expected": {
"type": "color",
"value": "#FFFFFFFF"
},
"variables": [
{
"type": "integer",
"name": "abc",
"value": 123
}
],
"platforms": [
"web"
]
},
{
"name": "getColorValue(nonexistentColorVar, fallback) => colorVal",
"expression": "@{getColorValue('abc', '#FFFFFFFF')}",
"expected": {
"type": "color",
"value": "#FFFFFFFF"
},
"variables": [],
"platforms": [
"web"
]
},
{
"name": "getColorValue(correctColorVar, fallback) => colorVal",
"expression": "@{getColorValue('abc', '#fff')}",
"expected": {
"type": "color",
"value": "#FF000000"
},
"variables": [
{
"type": "color",
"name": "abc",
"value": "#000"
}
],
"platforms": [
"web"
]
},
{
"name": "getColorValue(incorrectColorVar, fallback) => colorVal",
"expression": "@{getColorValue('abc', '#fff')}",
"expected": {
"type": "color",
"value": "#FFFFFFFF"
},
"variables": [
{
"type": "integer",
"name": "abc",
"value": 123
}
],
"platforms": [
"web"
]
},
{
"name": "getColorValue(nonexistentColorVar, fallback) => colorVal",
"expression": "@{getColorValue('abc', '#fff')}",
"expected": {
"type": "color",
"value": "#FFFFFFFF"
},
"variables": [],
"platforms": [
"web"
]
},
{
"name": "getUrlValue(correctUrlVar, fallback) => urlVal",
"expression": "@{getUrlValue('abc', fallback)}",
"expected": {
"type": "url",
"value": "https://var"
},
"variables": [
{
"type": "url",
"name": "abc",
"value": "https://var"
},
{
"type": "url",
"name": "fallback",
"value": "https://fallback"
}
],
"platforms": [
"web"
]
},
{
"name": "getUrlValue(incorrectUrlVar, fallback) => urlVal",
"expression": "@{getUrlValue('abc', fallback)}",
"expected": {
"type": "url",
"value": "https://fallback"
},
"variables": [
{
"type": "integer",
"name": "abc",
"value": 123
},
{
"type": "url",
"name": "fallback",
"value": "https://fallback"
}
],
"platforms": [
"web"
]
},
{
"name": "getUrlValue(nonexistentUrlVar, fallback) => urlVal",
"expression": "@{getUrlValue('abc', fallback)}",
"expected": {
"type": "url",
"value": "https://fallback"
},
"variables": [
{
"type": "url",
"name": "fallback",
"value": "https://fallback"
}
],
"platforms": [
"web"
]
},
{
"name": "getUrlValue(correctUrlVar, fallback) => urlVal",
"expression": "@{getUrlValue('abc', 'https://fallback')}",
"expected": {
"type": "url",
"value": "https://var"
},
"variables": [
{
"type": "url",
"name": "abc",
"value": "https://var"
}
],
"platforms": [
"web"
]
},
{
"name": "getUrlValue(incorrectUrlVar, fallback) => urlVal",
"expression": "@{getUrlValue('abc', 'https://fallback')}",
"expected": {
"type": "url",
"value": "https://fallback"
},
"variables": [
{
"type": "integer",
"name": "abc",
"value": 123
}
],
"platforms": [
"web"
]
},
{
"name": "getUrlValue(nonexistentUrlVar, fallback) => urlVal",
"expression": "@{getUrlValue('abc', 'https://fallback')}",
"expected": {
"type": "url",
"value": "https://fallback"
},
"variables": [],
"platforms": [
"web"
]
}
]
}