/* * This file is part of TREB. * * TREB is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any * later version. * * TREB is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along * with TREB. If not, see . * * Copyright 2022-2026 trebco, llc. * info@treb.app * */ /** * base type, for common data (atm only ID). id is intended to support * a unique ID within the context of a single parse pass. (NOTE: in theory * you could use the 'position' field... although that's not present in * all cases?) */ export interface BaseUnit { id: number; } export interface UnitLiteralNumber extends BaseUnit { type: 'literal'; position: number; value: number; text?: string; } export interface UnitLiteralString extends BaseUnit { type: 'literal'; position: number; value: string; text?: string; } export interface UnitLiteralBoolean extends BaseUnit { type: 'literal'; position: number; value: boolean; text?: string; } /** * expression unit representing a literal: string, number, boolean. * FIXME: would be nice if we had subtypes so we could specify * / export interface UnitLiteral extends BaseUnit { type: 'literal'; position: number; value: string | boolean | number; text?: string; } */ export type UnitLiteral = UnitLiteralNumber|UnitLiteralBoolean|UnitLiteralString; /** * testing: complex */ export interface UnitComplex extends BaseUnit { type: 'complex'; position: number; real: number; imaginary: number; text?: string; /** * this flag takes the place of the old "imaginary" unit type; * it's an indication that this unit has been composited, so don't * do it again. not sure this is actually needed by the parser... is it? */ composited?: boolean; } /* * * testing: complex * this represents just the imaginary part. it's for internal use and should * never be returned as a value. * / export interface UnitImaginary extends BaseUnit { type: 'imaginary'; position: number; value: number; text?: string; } */ /** * expression unit representing an array of primitive values. array * can contain mixed values, and holes. array cannot contain arrays, * or any other complex type (including complex, apparently. we should * remedy that). */ export interface UnitArray extends BaseUnit { type: 'array'; position: number; values: Array < Array >; } /** * expression unit representing a missing value, intended for missing * arguments in function calls. */ export interface UnitMissing extends BaseUnit { type: 'missing'; } /** * expression unit representing an opaque name or identifier. */ export interface UnitIdentifier extends BaseUnit { type: 'identifier'; position: number; name: string; } /** * "structured reference" for offset into named table */ export interface UnitStructuredReference extends BaseUnit { type: 'structured-reference'; label: string; position: number; table: string; /** * row refers to "this row". "all" means all values, including the * header. "column" means all values except the header. */ scope: 'row'|'all'|'column'; column: string; } /** * expression unit representing a group of units; like parentheses in an * expression. intended to prevent precendence reordering of operations. */ export interface UnitGroup extends BaseUnit { type: 'group'; elements: ExpressionUnit[]; // this flag indicates whether the group was expressly inserted by // the user (true) or generated as part of parsing (false). that // information is used when unparsing (reconstructing formula). explicit: boolean; } /** * expression unit representing a function call: has call and arguments. */ export interface UnitCall extends BaseUnit { type: 'call'; name: string; position: number; args: ExpressionUnit[]; /** testing */ end?: number; } /** * new call type: implicit. we might merge these. */ export interface UnitImplicitCall extends BaseUnit { type: 'implicit-call'; position: number; args: ExpressionUnit[]; call: ExpressionUnit; } /** * this isn't an output type (unless parsing fails), but it's useful * to be able to pass these around with the same semantics. */ export interface UnitOperator extends BaseUnit { type: 'operator'; position: number; operator: string; } /** * also not an output type */ export interface UnitGroupSeparator extends BaseUnit { type: 'group-separator'; position: number; } /** * expression unit representing a binary operation. operations may be * re-ordered based on precendence. */ export interface UnitBinary extends BaseUnit { type: 'binary'; left: ExpressionUnit; operator: string; right: ExpressionUnit; position: number; // this is the _operator_ position, since that will be the error } /** * expression unit representing a unary operation. */ export interface UnitUnary extends BaseUnit { type: 'unary'; operator: string; operand: ExpressionUnit; position: number; } /** * expression unit representing a spreadsheet address */ export interface UnitAddress extends BaseUnit { type: 'address'; sheet?: string; sheet_id?: number; label: string; row: number; column: number; absolute_row?: boolean; absolute_column?: boolean; /** spill flag (address ends with #) */ spill?: boolean; /** * this means the row is a relative offset from the current row. this * happens if you use R1C1 syntax with square brackets. */ offset_row?: boolean; /** * this means the column is a relative offset from the current column. * this happens if you use R1C1 syntax with square brackets. */ offset_column?: boolean; /** the formula was originally in R1C1. we probably want to translate it. */ r1c1?: boolean; position: number; } /** * expression unit representing a spreadsheet range */ export interface UnitRange extends BaseUnit { type: 'range'; label: string; start: UnitAddress; end: UnitAddress; position: number; } export interface UnitDimensionedQuantity extends BaseUnit { type: 'dimensioned'; expression: BaseExpressionUnit; //