import {isValue, typeOf} from '../values'; import type {Type} from '../types'; import type {Value} from '../values'; import type {Expression} from '../expression'; import type ParsingContext from '../parsing_context'; class Literal implements Expression { type: Type; value: Value; constructor(type: Type, value: Value) { this.type = type; this.value = value; } static parse(args: ReadonlyArray, context: ParsingContext): Expression { if (args.length !== 2) return context.error(`'literal' expression requires exactly one argument, but found ${args.length - 1} instead.`) as null; if (!isValue(args[1])) return context.error('invalid value') as null; const value = (args[1] as any); let type = typeOf(value); // special case: infer the item type if possible for zero-length arrays const expected = context.expectedType; if ( type.kind === 'array' && type.N === 0 && expected && expected.kind === 'array' && (typeof expected.N !== 'number' || expected.N === 0) ) { type = expected; } return new Literal(type, value); } evaluate() { return this.value; } eachChild() {} outputDefined() { return true; } } export default Literal;