@trebco/treb 31.8.2 → 32.1.1

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.
Files changed (43) hide show
  1. package/dist/treb-spreadsheet.mjs +8 -8
  2. package/i18n/languages/treb-i18n-da.mjs +1 -0
  3. package/i18n/languages/treb-i18n-de.mjs +1 -0
  4. package/i18n/languages/treb-i18n-es.mjs +1 -0
  5. package/i18n/languages/treb-i18n-fr.mjs +1 -0
  6. package/i18n/languages/treb-i18n-it.mjs +1 -0
  7. package/i18n/languages/treb-i18n-nl.mjs +1 -0
  8. package/i18n/languages/treb-i18n-no.mjs +1 -0
  9. package/i18n/languages/treb-i18n-pl.mjs +1 -0
  10. package/i18n/languages/treb-i18n-pt.mjs +1 -0
  11. package/i18n/languages/treb-i18n-sv.mjs +1 -0
  12. package/package.json +2 -2
  13. package/treb-base-types/src/union.ts +6 -0
  14. package/treb-base-types/src/value-type.ts +13 -0
  15. package/treb-calculator/src/calculator.ts +18 -1
  16. package/treb-calculator/src/descriptors.ts +42 -3
  17. package/treb-calculator/src/expression-calculator.ts +182 -6
  18. package/treb-calculator/src/functions/base-functions.ts +48 -0
  19. package/treb-calculator/src/functions/lambda-functions.ts +96 -0
  20. package/treb-data-model/src/data_model.ts +28 -13
  21. package/treb-data-model/src/named.ts +7 -0
  22. package/treb-data-model/src/sheet.ts +17 -0
  23. package/treb-embed/src/embedded-spreadsheet.ts +12 -3
  24. package/treb-embed/style/autocomplete.scss +4 -0
  25. package/treb-embed/style/dropdown-select.scss +3 -0
  26. package/treb-embed/style/font-stacks.scss +2 -0
  27. package/treb-embed/style/grid.scss +11 -11
  28. package/treb-embed/style/layout.scss +12 -9
  29. package/treb-embed/style/mouse-mask.scss +3 -0
  30. package/treb-embed/style/note.scss +4 -0
  31. package/treb-embed/style/overlay-editor.scss +3 -0
  32. package/treb-embed/style/tab-bar.scss +4 -0
  33. package/treb-embed/style/table.scss +3 -0
  34. package/treb-embed/style/theme-defaults.scss +2 -22
  35. package/treb-embed/style/tooltip.scss +4 -0
  36. package/treb-embed/style/treb-spreadsheet-element.scss +1 -1
  37. package/treb-export/src/workbook-style2.ts +0 -39
  38. package/treb-grid/src/render/svg_selection_block.ts +1 -37
  39. package/treb-grid/src/types/grid.ts +4 -3
  40. package/treb-parser/src/parser-types.ts +21 -0
  41. package/treb-parser/src/parser.ts +126 -218
  42. package/dist/treb-export-worker.mjs +0 -2
  43. package/dist/treb.d.ts +0 -2235
@@ -0,0 +1 @@
1
+ export const LanguageMap = {"language":"PT","created":"Wed, 25 Sep 2024 19:20:26 GMT","version":"2.1.3","functions":[{"base":"ADDRESS","name":"ENDEREÇO","arguments":["linha","coluna","absoluto","a1","nome da planilha"]},{"base":"AND","name":"E"},{"base":"ARG","name":"ARG","description":"Retorna o argumento principal de um número complexo (em radianos)"},{"base":"ASIN","name":"ASEN"},{"base":"ASINH","name":"ASENH"},{"base":"AVERAGE","name":"MÉDIA","description":"Retorna a média aritmética de todos os argumentos numéricos"},{"base":"AVERAGEIF","name":"MÉDIA.SE","arguments":["intervalo","critério"]},{"base":"AVERAGEIFS","name":"MÉDIA.SE.S","arguments":["intervalo de valores","intervalo de critérios","critério","intervalo de critérios","critério"]},{"base":"BETA.DIST","name":"DIST.BETA","description":"Distribuição beta","arguments":["x","a","b","cumulativo"]},{"base":"BETA.INV","name":"INV.BETA","description":"Inverso da distribuição beta","arguments":["probabilidade","a","b"]},{"base":"CEILING","name":"ARRED.EXCESSO"},{"base":"CELL","name":"CÉL","description":"Retorna dados sobre uma célula","arguments":["tipo","referência"]},{"base":"CHAR","name":"CARÁT","arguments":["número"]},{"base":"CHECKBOX","name":"CHECKBOX","arguments":["marcado"]},{"base":"CHOOSE","name":"SELECIONAR","description":"Retorna uma das escolhas de uma lista","arguments":["Índice selecionado","Escolha 1..."]},{"base":"CODE","name":"CÓDIGO","arguments":["texto"]},{"base":"COLUMN","name":"COL","arguments":["referência"]},{"base":"COLUMNS","name":"COLS","arguments":["referência"]},{"base":"COMPLEX","name":"COMPLEXO","description":"Garante que o valor dado será tratado como um número complexo"},{"base":"COMPLEXLOG","name":"COMPLEXLOG","description":"Retorna o valor principal Log(z) de um número complexo z"},{"base":"CONCAT","name":"CONCAT","description":"Cola strings juntas"},{"base":"CONCATENATE","name":"CONCATENAR","description":"Cola strings juntas"},{"base":"CONJUGATE","name":"CONJUGATE","description":"Retorna o conjugado de um número complexo"},{"base":"CORREL","name":"CORREL","description":"Retorna a correlação entre dois intervalos de valores","arguments":["A","B"]},{"base":"COS","name":"COS","arguments":["ângulo em radianos"]},{"base":"COSH","name":"COSH","arguments":["número"]},{"base":"COUNT","name":"CONTAR","description":"Conta células que contêm números"},{"base":"COUNTA","name":"CONTAR.VAL","description":"Conta células que não estão vazias"},{"base":"COUNTIF","name":"CONTAR.SE","arguments":["intervalo","critério"]},{"base":"COUNTIFS","name":"CONTAR.SE.S","arguments":["intervalo","critério","intervalo","critério"]},{"base":"COVAR","name":"COVAR","description":"Retorna a covariância entre dois intervalos de valores","arguments":["A","B"]},{"base":"CUMIPMT","name":"PGTOJURACUM","description":"Retorna o juro acumulado pago em um empréstimo entre dois períodos","arguments":["Taxa","Períodos","Valor Presente","Período Inicial","Período Final","Tipo"]},{"base":"CUMPRINC","name":"PGTOCAPACUM","description":"Retorna o principal acumulado pago em um empréstimo entre dois períodos","arguments":["Taxa","Períodos","Valor Presente","Período Inicial","Período Final","Tipo"]},{"base":"DATE","name":"DATA","description":"Constrói uma data a partir de ano/mês/dia","arguments":["ano","mês","dia"]},{"base":"DAY","name":"DIA","description":"Retorna o dia do mês de uma data","arguments":["data"]},{"base":"DEGREES","name":"GRAUS","description":"Converte radianos para graus","arguments":["Radianos"]},{"base":"DELTA","name":"DELTA","arguments":["número","número"]},{"base":"EDATE","name":"DATAM","arguments":["Data inicial","Meses"]},{"base":"EOMONTH","name":"FIMMÊS","arguments":["Data inicial","Meses"]},{"base":"ERF","name":"FUNCERRO"},{"base":"EXACT","name":"EXATO","arguments":["texto","texto"]},{"base":"FACT","name":"FATORIAL","description":"Retorna o fatorial de um número","arguments":["número"]},{"base":"FILTER","name":"FILTER","description":"Filtra uma matriz usando uma segunda matriz","arguments":["origem","filtro"]},{"base":"FIND","name":"LOCALIZAR","description":"Encontra uma string (agulha) em outra string (palheiro). Sensível a maiúsculas e minúsculas.","arguments":["Agulha","Palheiro","Início"]},{"base":"FLOOR","name":"ARRED.DEFEITO"},{"base":"FORMULATEXT","name":"FÓRMULA.TEXTO","description":"Retorna uma fórmula como uma string","arguments":["referência"]},{"base":"FV","name":"VF","description":"Retorna o valor futuro de um investimento","arguments":["Taxa","Períodos","Pagamento","Valor Presente","Tipo"]},{"base":"GAMMA","name":"GAMA","description":"Retorna a função gama para o valor dado","arguments":["valor"]},{"base":"GAMMALN","name":"LNGAMA","description":"Retorna o logaritmo natural da função gama","arguments":["valor"]},{"base":"GAMMALN.PRECISE","name":"LNGAMA.PRECISO","description":"Retorna o logaritmo natural da função gama","arguments":["valor"]},{"base":"GCD","name":"MDC","description":"Encontra o máximo divisor comum dos argumentos"},{"base":"GEOMEAN","name":"MÉDIA.GEOMÉTRICA","description":"Retorna a média geométrica de todos os argumentos numéricos"},{"base":"HARMEAN","name":"MÉDIA.HARMÓNICA","description":"Retorna a média harmônica dos argumentos"},{"base":"HLOOKUP","name":"PROCH","arguments":["Valor de pesquisa","Tabela","Índice do resultado","Inexato"]},{"base":"IF","name":"SE","arguments":["valor de teste","valor se verdadeiro","valor se falso"]},{"base":"IFERROR","name":"SE.ERRO","description":"Retorna o valor original ou o valor alternativo se o valor original contiver um erro","arguments":["valor original","valor alternativo"]},{"base":"IMAGINARY","name":"IMAGINÁRIO","description":"Retorna a parte imaginária de um número complexo (como real)"},{"base":"INDEX","name":"ÍNDICE","arguments":["intervalo","linha","coluna"]},{"base":"INDIRECT","name":"INDIRECTO","arguments":["referência"]},{"base":"INTERCEPT","name":"INTERCETAR","arguments":["y_conhecidos","x_conhecidos"]},{"base":"IPMT","name":"IPGTO","description":"Retorna a parte de juros de um pagamento","arguments":["Taxa","Período","Períodos","Valor Presente","Valor Futuro","Tipo"]},{"base":"IRR","name":"TIR","description":"Calcula a taxa interna de retorno de uma série de fluxos de caixa","arguments":["Fluxos de caixa","Estimativa"]},{"base":"ISBLANK","name":"É.CÉL.VAZIA","description":"Retorna verdadeiro se a referência estiver em branco","arguments":["Referência"]},{"base":"ISCOMPLEX","name":"ISCOMPLEX","description":"Retorna verdadeiro se a referência for um número complexo","arguments":["Referência"]},{"base":"ISERR","name":"É.ERROS","description":"Verifica se outra célula contém um erro","arguments":["referência"]},{"base":"ISERROR","name":"É.ERRO","description":"Verifica se outra célula contém um erro","arguments":["referência"]},{"base":"ISFORMULA","name":"É.FORMULA","description":"Retorna verdadeiro se a referência for uma fórmula","arguments":["Referência"]},{"base":"ISLOGICAL","name":"É.LÓGICO","description":"Retorna verdadeiro se a referência for um VERDADEIRO ou FALSO lógico","arguments":["Referência"]},{"base":"ISNA","name":"É.NÃO.DISP","description":"Verifica se outra célula contém um erro #NA","arguments":["referência"]},{"base":"ISNUMBER","name":"É.NÚM","description":"Retorna verdadeiro se a referência for um número","arguments":["Referência"]},{"base":"ISTEXT","name":"É.TEXTO","description":"Retorna verdadeiro se a referência for texto","arguments":["Referência"]},{"base":"LARGE","name":"MAIOR","description":"Retorna o enésimo valor numérico dos dados em ordem decrescente","arguments":["valores","índice"]},{"base":"LCM","name":"MMC","description":"Retorna o mínimo múltiplo comum dos argumentos"},{"base":"LEFT","name":"ESQUERDA","arguments":["texto","contagem"]},{"base":"LEN","name":"NÚM.CARACT","arguments":["texto"]},{"base":"LOWER","name":"MINÚSCULAS","description":"Converte texto para minúsculas","arguments":["texto"]},{"base":"MATCH","name":"CORRESP","arguments":["valor","intervalo","tipo"]},{"base":"MAX","name":"MÁXIMO"},{"base":"MDETERM","name":"MATRIZ.DETERM","description":"Retorna o determinante de uma matriz","arguments":["matriz"]},{"base":"MEAN","name":"MEAN","description":"Retorna a média aritmética de todos os argumentos numéricos"},{"base":"MEDIAN","name":"MED","description":"Retorna o valor mediano do intervalo de dados","arguments":["intervalo"]},{"base":"MID","name":"SEG.TEXTO","arguments":["texto","esquerda","contagem"]},{"base":"MIN","name":"MÍNIMO"},{"base":"MINVERSE","name":"MATRIZ.INVERSA","description":"Retorna a matriz inversa","arguments":["matriz"]},{"base":"MMULT","name":"MATRIZ.MULT","description":"Retorna o produto escalar A ⋅ B","arguments":["A","B"]},{"base":"MOD","name":"RESTO"},{"base":"MONTH","name":"MÊS","description":"Retorna o mês de uma data","arguments":["data"]},{"base":"NORM.DIST","name":"DIST.NORM","description":"Distribuição normal cumulativa","arguments":["valor","média","desvio padrão","cumulativo"]},{"base":"NORM.INV","name":"INV.NORM","description":"Inverso da distribuição normal cumulativa","arguments":["probabilidade","média","desvio padrão"]},{"base":"NORM.S.DIST","name":"DIST.S.NORM","description":"Distribuição normal cumulativa","arguments":["valor","cumulativo"]},{"base":"NORM.S.INV","name":"INV.S.NORM","description":"Inverso da distribuição normal padrão cumulativa","arguments":["probabilidade"]},{"base":"NORMSDIST","name":"DIST.NORMP","description":"Distribuição normal cumulativa","arguments":["valor","cumulativo"]},{"base":"NORMSINV","name":"INV.NORMP","description":"Inverso da distribuição normal padrão cumulativa","arguments":["probabilidade"]},{"base":"NOT","name":"NÃO"},{"base":"NOW","name":"AGORA","description":"Retorna a hora atual"},{"base":"NPER","name":"NPER","description":"Retorna o número de períodos de um investimento","arguments":["Taxa","Pagamento","Valor Presente","Valor Futuro","Tipo"]},{"base":"NPV","name":"VAL","description":"Retorna o valor presente de uma série de fluxos de caixa futuros","arguments":["Taxa","Fluxo de Caixa"]},{"base":"OFFSET","name":"DESLOCAMENTO","arguments":["referência","linhas","colunas","altura","largura"]},{"base":"OR","name":"OU"},{"base":"PERCENTILE","name":"PERCENTIL","description":"Retorna o valor do k-ésimo percentil do intervalo de dados","arguments":["intervalo","percentil"]},{"base":"PHI","name":"PHII","arguments":["x"]},{"base":"PMT","name":"PGTO","description":"Retorna o pagamento periódico de um empréstimo","arguments":["Taxa","Períodos","Valor Presente","Valor Futuro","Tipo"]},{"base":"POWER","name":"POTÊNCIA","description":"Retorna a base elevada à potência dada","arguments":["base","expoente"]},{"base":"PPMT","name":"PPGTO","description":"Retorna a parte principal de um pagamento","arguments":["Taxa","Período","Períodos","Valor Presente","Valor Futuro","Tipo"]},{"base":"PRODUCT","name":"PRODUTO"},{"base":"PV","name":"VA","description":"Retorna o valor presente de um investimento","arguments":["Taxa","Períodos","Pagamento","Valor Futuro","Tipo"]},{"base":"QUARTILE","name":"QUARTIL","description":"Retorna o quartil interpolado do conjunto de dados (incluindo a mediana)","arguments":["intervalo","quartil"]},{"base":"QUARTILE.EXC","name":"QUARTIL.EXC","description":"Retorna o quartil interpolado do conjunto de dados (excluindo a mediana)","arguments":["intervalo","quartil"]},{"base":"QUARTILE.INC","name":"QUARTIL.INC","description":"Retorna o quartil interpolado do conjunto de dados (incluindo a mediana)","arguments":["intervalo","quartil"]},{"base":"RADIANS","name":"RADIANOS","description":"Converte graus para radianos","arguments":["Graus"]},{"base":"RAND","name":"ALEATÓRIO"},{"base":"RANDBETWEEN","name":"ALEATÓRIOENTRE","arguments":["mínimo","máximo"]},{"base":"RANK","name":"ORDEM","arguments":["Valor","Origem","Ordem"]},{"base":"RATE","name":"TAXA","description":"Retorna a taxa de juros de um empréstimo","arguments":["Períodos","Pagamento","Valor Presente","Valor Futuro","Tipo"]},{"base":"REAL","name":"REAL","description":"Retorna a parte real de um número complexo"},{"base":"RECTANGULAR","name":"RECTANGULAR","description":"Converte um número complexo da forma polar para a forma retangular","arguments":["r","θ em radianos"]},{"base":"REGEXEXTRACT","name":"REGEXEXTRACT","description":"Extrai texto usando uma expressão regular","arguments":["texto","padrão","modo de retorno","insensível a maiúsculas e minúsculas"]},{"base":"REGEXREPLACE","name":"REGEXREPLACE","description":"Substitui texto em uma string usando uma regex","arguments":["texto","padrão","substituição","ocorrência","insensível a maiúsculas e minúsculas"]},{"base":"REGEXTEST","name":"REGEXTEST","description":"Compara texto com uma expressão regular","arguments":["texto","padrão","insensível a maiúsculas e minúsculas"]},{"base":"RIGHT","name":"DIREITA","arguments":["texto","contagem"]},{"base":"ROUND","name":"ARREDONDAR"},{"base":"ROUNDDOWN","name":"ARRED.PARA.BAIXO"},{"base":"ROUNDUP","name":"ARRED.PARA.CIMA"},{"base":"ROW","name":"LINHA","arguments":["referência"]},{"base":"ROWS","name":"LINS","arguments":["referência"]},{"base":"SEARCH","name":"PROCURAR","description":"Encontra uma string (agulha) em outra string (palheiro). Não diferencia maiúsculas de minúsculas.","arguments":["Agulha","Palheiro","Início"]},{"base":"SEQUENCE","name":"SEQUENCE","arguments":["linhas","colunas","início","passo"]},{"base":"SIGN","name":"SINAL"},{"base":"SIMPLIFY","name":"SIMPLIFY","arguments":["valor","dígitos significativos"]},{"base":"SIN","name":"SEN","arguments":["ângulo em radianos"]},{"base":"SINH","name":"SENH","arguments":["número"]},{"base":"SLOPE","name":"DECLIVE","arguments":["y_conhecidos","x_conhecidos"]},{"base":"SMALL","name":"MENOR","description":"Retorna o enésimo valor numérico dos dados em ordem crescente","arguments":["valores","índice"]},{"base":"SORT","name":"SORT","arguments":["valores"]},{"base":"SPARKLINE.COLUMN","name":"SPARKLINE.COLUMN","arguments":["dados","cor","cor negativa"]},{"base":"SPARKLINE.LINE","name":"SPARKLINE.LINE","arguments":["dados","cor","largura da linha"]},{"base":"SQRT","name":"RAIZQ","description":"Retorna a raiz quadrada do argumento"},{"base":"STDEV","name":"DESVPAD","description":"Retorna o desvio padrão de um conjunto de valores correspondente a uma amostra de uma população","arguments":["dados"]},{"base":"STDEV.P","name":"DESVPAD.P","description":"Retorna o desvio padrão de um conjunto de valores correspondente a uma população","arguments":["dados"]},{"base":"STDEV.S","name":"DESVPAD.S","description":"Retorna o desvio padrão de um conjunto de valores correspondente a uma amostra de uma população","arguments":["dados"]},{"base":"STDEVA","name":"DESVPADA","description":"Retorna o desvio padrão de um conjunto de valores correspondente a uma amostra de uma população","arguments":["dados"]},{"base":"STDEVPA","name":"DESVPADPA","description":"Retorna o desvio padrão de um conjunto de valores correspondente a uma população","arguments":["dados"]},{"base":"SUBSTITUTE","name":"SUBST","arguments":["texto","procurar","substituição","índice"]},{"base":"SUBTOTAL","name":"SUBTOTAL","arguments":["tipo","intervalo"]},{"base":"SUM","name":"SOMA","description":"Soma argumentos e intervalos","arguments":["valores ou intervalos"]},{"base":"SUMIF","name":"SOMA.SE","arguments":["intervalo","critério"]},{"base":"SUMIFS","name":"SOMA.SE.S","arguments":["intervalo de valores","intervalo de critérios","critério","intervalo de critérios","critério"]},{"base":"SUMPRODUCT","name":"SOMARPRODUTO","description":"Retorna a soma dos produtos emparelhados de dois ou mais intervalos"},{"base":"SUMSQ","name":"SOMARQUAD","description":"Retorna a soma dos quadrados de todos os argumentos","arguments":["valores ou intervalos"]},{"base":"TAN","name":"TAN","arguments":["ângulo em radianos"]},{"base":"TANH","name":"TANH","arguments":["número"]},{"base":"TEXT","name":"TEXTO","arguments":["valor","formato numérico"]},{"base":"TODAY","name":"HOJE","description":"Retorna o dia atual"},{"base":"TRANSPOSE","name":"TRANSPOR","description":"Retorna a transposta da matriz de entrada","arguments":["matriz"]},{"base":"TRUNC","name":"TRUNCAR"},{"base":"UPPER","name":"MAIÚSCULAS","description":"Converte texto para maiúsculas","arguments":["texto"]},{"base":"VALUE","name":"VALOR","arguments":["texto"]},{"base":"VAR","name":"VAR","description":"Retorna a variância de um conjunto de valores correspondente a uma amostra de uma população","arguments":["dados"]},{"base":"VAR.P","name":"VAR.P","description":"Retorna a variância de um conjunto de valores correspondente a uma população","arguments":["dados"]},{"base":"VAR.S","name":"VAR.S","description":"Retorna a variância de um conjunto de valores correspondente a uma amostra de uma população","arguments":["dados"]},{"base":"VLOOKUP","name":"PROCV","arguments":["Valor de pesquisa","Tabela","Índice do resultado","Inexato"]},{"base":"XIRR","name":"XTIR","description":"Retorna a taxa interna de retorno de um fluxo não periódico de pagamentos","arguments":["Valores","Datas","Estimativa"]},{"base":"XLOOKUP","name":"XVAL","arguments":["Valor de pesquisa","Matriz de pesquisa","Matriz de retorno","Não encontrado","Modo de correspondência","Modo de pesquisa"]},{"base":"XNPV","name":"XOR","description":"Retorna o VPL de um fluxo não periódico de pagamentos a uma determinada taxa","arguments":["Taxa de desconto","Valores","Datas"]},{"base":"YEAR","name":"FRACÇÃOANO","description":"Retorna o ano de uma data","arguments":["data"]},{"base":"YEARFRAC","name":"LUCRO","description":"Retorna a fração de um ano entre duas datas","arguments":["Início","Fim","Base"]},{"base":"Z.TEST","name":"TESTE.Z","arguments":["Matriz","x","Sigma"]}]};
@@ -0,0 +1 @@
1
+ export const LanguageMap = {"language":"SV","created":"Wed, 25 Sep 2024 19:20:26 GMT","version":"2.1.3","functions":[{"base":"ACOS","name":"ARCCOS"},{"base":"ACOSH","name":"ARCCOSH"},{"base":"ADDRESS","name":"ADRESS","arguments":["rad","kolumn","absolut","a1","blad namn"]},{"base":"AND","name":"OCH"},{"base":"ARG","name":"ARG","description":"Returnerar huvudargumentet för ett komplext tal (i radianer)"},{"base":"ASIN","name":"ARCSIN"},{"base":"ASINH","name":"ARCSINH"},{"base":"ATAN","name":"ARCTAN"},{"base":"ATAN2","name":"ARCTAN2"},{"base":"ATANH","name":"ARCTANH"},{"base":"AVERAGE","name":"MEDEL","description":"Returnerar det aritmetiska medelvärdet av alla numeriska argument"},{"base":"AVERAGEIF","name":"MEDELOM","arguments":["intervall","villkor"]},{"base":"AVERAGEIFS","name":"MEDEL.OMF","arguments":["värdeintervall","villkorsintervall","villkor","villkorsintervall","villkor"]},{"base":"BETA.DIST","name":"BETA.FÖRD","description":"Beta-fördelning","arguments":["x","a","b","kumulativ"]},{"base":"BETA.INV","name":"BETA.INV","description":"Invers av beta-fördelningen","arguments":["sannolikhet","a","b"]},{"base":"CEILING","name":"RUNDA.UPP"},{"base":"CELL","name":"CELL","description":"Returnerar data om en cell","arguments":["typ","referens"]},{"base":"CHAR","name":"TECKENKOD","arguments":["nummer"]},{"base":"CHECKBOX","name":"CHECKBOX","arguments":["markerad"]},{"base":"CHOOSE","name":"VÄLJ","description":"Returnerar ett av en lista med val","arguments":["Valt index","Val 1..."]},{"base":"CODE","name":"KOD","arguments":["sträng"]},{"base":"COLUMN","name":"KOLUMN","arguments":["referens"]},{"base":"COLUMNS","name":"KOLUMNER","arguments":["referens"]},{"base":"COMPLEX","name":"KOMPLEX","description":"Säkerställer att det givna värdet behandlas som ett komplext tal"},{"base":"COMPLEXLOG","name":"COMPLEXLOG","description":"Returnerar huvudvärdet Log(z) av ett komplext tal z"},{"base":"CONCAT","name":"CONCAT","description":"Sammanfogar strängar"},{"base":"CONCATENATE","name":"SAMMANFOGA","description":"Sammanfogar strängar"},{"base":"CONJUGATE","name":"CONJUGATE","description":"Returnerar konjugatet av ett komplext tal"},{"base":"CORREL","name":"KORREL","description":"Returnerar korrelationen mellan två värdeintervall","arguments":["A","B"]},{"base":"COS","name":"COS","arguments":["vinkel i radianer"]},{"base":"COSH","name":"COSH","arguments":["tal"]},{"base":"COUNT","name":"ANTAL","description":"Räknar celler som innehåller tal"},{"base":"COUNTA","name":"ANTALV","description":"Räknar celler som inte är tomma"},{"base":"COUNTIF","name":"ANTAL.OM","arguments":["intervall","villkor"]},{"base":"COUNTIFS","name":"ANTAL.OMF","arguments":["intervall","villkor","intervall","villkor"]},{"base":"COVAR","name":"KOVAR","description":"Returnerar kovariansen mellan två värdeintervall","arguments":["A","B"]},{"base":"CUMIPMT","name":"KUMRÄNTA","description":"Returnerar kumulativ ränta betald på ett lån mellan två perioder","arguments":["Ränta","Perioder","Nuvärde","Startperiod","Slutperiod","Typ"]},{"base":"CUMPRINC","name":"KUMPRIS","description":"Returnerar kumulativt kapital betalt på ett lån mellan två perioder","arguments":["Ränta","Perioder","Nuvärde","Startperiod","Slutperiod","Typ"]},{"base":"DATE","name":"DATUM","description":"Konstruerar ett datum från år/månad/dag","arguments":["år","månad","dag"]},{"base":"DAY","name":"DAG","description":"Returnerar dag i månaden från ett datum","arguments":["datum"]},{"base":"DEGREES","name":"GRADER","description":"Konverterar radianer till grader","arguments":["Radianer"]},{"base":"DELTA","name":"DELTA","arguments":["tal","tal"]},{"base":"EDATE","name":"EDATUM","arguments":["Startdatum","Månader"]},{"base":"EOMONTH","name":"SLUTMÅNAD","arguments":["Startdatum","Månader"]},{"base":"ERF","name":"FELF"},{"base":"EXACT","name":"EXAKT","arguments":["text","text"]},{"base":"FACT","name":"FAKULTET","description":"Returnerar fakulteten av ett tal","arguments":["tal"]},{"base":"FILTER","name":"FILTER","description":"Filtrera en array med hjälp av en andra array","arguments":["källa","filter"]},{"base":"FIND","name":"HITTA","description":"Hitta en sträng (nål) i en annan sträng (höstack). Skiftlägeskänslig.","arguments":["Nål","Höstack","Start"]},{"base":"FLOOR","name":"RUNDA.NED"},{"base":"FORMULATEXT","name":"FORMELTEXT","description":"Returnerar en formel som en sträng","arguments":["referens"]},{"base":"FV","name":"SLUTVÄRDE","description":"Returnerar slutvärdet av en investering","arguments":["Ränta","Perioder","Betalning","Nuvärde","Typ"]},{"base":"GAMMA","name":"GAMMA","description":"Returnerar gammafunktionen för det givna värdet","arguments":["värde"]},{"base":"GAMMALN","name":"GAMMALN","description":"Returnerar den naturliga logaritmen av gammafunktionen","arguments":["värde"]},{"base":"GAMMALN.PRECISE","name":"GAMMALN.EXAKT","description":"Returnerar den naturliga logaritmen av gammafunktionen","arguments":["värde"]},{"base":"GCD","name":"SGD","description":"Hittar den största gemensamma delaren av argumenten"},{"base":"GEOMEAN","name":"GEOMEDEL","description":"Returnerar det geometriska medelvärdet av alla numeriska argument"},{"base":"HARMEAN","name":"HARMMEDEL","description":"Returnerar det harmoniska medelvärdet av argumenten"},{"base":"HLOOKUP","name":"LETAKOLUMN","arguments":["Sökvärde","Tabell","Resultatindex","Inexakt"]},{"base":"IF","name":"OM","arguments":["testvärde","värde om sant","värde om falskt"]},{"base":"IFERROR","name":"OMFEL","description":"Returnerar originalvärdet eller det alternativa värdet om originalvärdet innehåller ett fel","arguments":["originalvärde","alternativt värde"]},{"base":"IMAGINARY","name":"IMAGINÄR","description":"Returnerar den imaginära delen av ett komplext tal (som reellt)"},{"base":"INDEX","name":"INDEX","arguments":["intervall","rad","kolumn"]},{"base":"INDIRECT","name":"INDIREKT","arguments":["referens"]},{"base":"INT","name":"HELTAL"},{"base":"INTERCEPT","name":"SKÄRNINGSPUNKT","arguments":["kända_y","kända_x"]},{"base":"IPMT","name":"RBETALNING","description":"Returnerar räntedelen av en betalning","arguments":["Ränta","Period","Perioder","Nuvärde","Framtida värde","Typ"]},{"base":"IRR","name":"IR","description":"Beräknar den interna avkastningsgraden för en serie kassaflöden","arguments":["Kassaflöden","Gissning"]},{"base":"ISBLANK","name":"ÄRTOM","description":"Returnerar sant om referensen är tom","arguments":["Referens"]},{"base":"ISCOMPLEX","name":"ISCOMPLEX","description":"Returnerar sant om referensen är ett komplext tal","arguments":["Referens"]},{"base":"ISERR","name":"ÄRF","description":"Kontrollerar om en annan cell innehåller ett fel","arguments":["referens"]},{"base":"ISERROR","name":"ÄRFEL","description":"Kontrollerar om en annan cell innehåller ett fel","arguments":["referens"]},{"base":"ISFORMULA","name":"ÄRFORMEL","description":"Returnerar sant om referensen är en formel","arguments":["Referens"]},{"base":"ISLOGICAL","name":"ÄRLOGISK","description":"Returnerar sant om referensen är ett logiskt SANT eller FALSKT","arguments":["Referens"]},{"base":"ISNA","name":"ÄRSAKNAD","description":"Kontrollerar om en annan cell innehåller ett #N/A-fel","arguments":["referens"]},{"base":"ISNUMBER","name":"ÄRTAL","description":"Returnerar sant om referensen är ett tal","arguments":["Referens"]},{"base":"ISTEXT","name":"ÄRTEXT","description":"Returnerar sant om referensen är text","arguments":["Referens"]},{"base":"LARGE","name":"STÖRSTA","description":"Returnerar det n:te numeriska värdet från data i fallande ordning","arguments":["värden","index"]},{"base":"LCM","name":"MGM","description":"Returnerar den minsta gemensamma multipeln av argumenten"},{"base":"LEFT","name":"VÄNSTER","arguments":["sträng","antal"]},{"base":"LEN","name":"LÄNGD","arguments":["sträng"]},{"base":"LOWER","name":"GEMENER","description":"Konverterar text till gemener","arguments":["text"]},{"base":"MATCH","name":"PASSA","arguments":["värde","intervall","typ"]},{"base":"MDETERM","name":"MDETERM","description":"Returnerar determinanten av en matris","arguments":["matris"]},{"base":"MEAN","name":"MEAN","description":"Returnerar det aritmetiska medelvärdet av alla numeriska argument"},{"base":"MEDIAN","name":"MEDIAN","description":"Returnerar medianvärdet av dataintervallets värden","arguments":["intervall"]},{"base":"MID","name":"EXTEXT","arguments":["sträng","vänster","antal"]},{"base":"MINVERSE","name":"MINVERT","description":"Returnerar den inversa matrisen","arguments":["matris"]},{"base":"MMULT","name":"MMULT","description":"Returnerar skalärprodukten A ⋅ B","arguments":["A","B"]},{"base":"MOD","name":"REST"},{"base":"MONTH","name":"MÅNAD","description":"Returnerar månad från datum","arguments":["datum"]},{"base":"NORM.DIST","name":"NORM.FÖRD","description":"Kumulativ normalfördelning","arguments":["värde","medelvärde","standardavvikelse","kumulativ"]},{"base":"NORM.INV","name":"NORM.INV","description":"Invers av den kumulativa normalfördelningen","arguments":["sannolikhet","medelvärde","standardavvikelse"]},{"base":"NORM.S.DIST","name":"NORM.S.FÖRD","description":"Kumulativ normalfördelning","arguments":["värde","kumulativ"]},{"base":"NORM.S.INV","name":"NORM.S.INV","description":"Invers av den kumulativa standardnormalfördelningen","arguments":["sannolikhet"]},{"base":"NORMSDIST","name":"NORMSFÖRD","description":"Kumulativ normalfördelning","arguments":["värde","kumulativ"]},{"base":"NORMSINV","name":"NORMSINV","description":"Invers av den kumulativa standardnormalfördelningen","arguments":["sannolikhet"]},{"base":"NOT","name":"ICKE"},{"base":"NOW","name":"NU","description":"Returnerar aktuell tid"},{"base":"NPER","name":"PERIODER","description":"Returnerar antalet perioder för en investering","arguments":["Ränta","Betalning","Nuvärde","Framtida värde","Typ"]},{"base":"NPV","name":"NETNUVÄRDE","description":"Returnerar nuvärdet av en serie framtida kassaflöden","arguments":["Ränta","Kassaflöde"]},{"base":"OFFSET","name":"FÖRSKJUTNING","arguments":["referens","rader","kolumner","höjd","bredd"]},{"base":"OR","name":"ELLER"},{"base":"PERCENTILE","name":"PERCENTIL","description":"Returnerar det k:te percentilvärdet från dataintervallets värden","arguments":["intervall","percentil"]},{"base":"PHI","name":"PHI","arguments":["x"]},{"base":"PMT","name":"BETALNING","description":"Returnerar den periodiska betalningen för ett lån","arguments":["Ränta","Perioder","Nuvärde","Framtida värde","Typ"]},{"base":"POWER","name":"UPPHÖJT.TILL","description":"Returnerar basen upphöjd till den givna exponenten","arguments":["bas","exponent"]},{"base":"PPMT","name":"AMORT","description":"Returnerar kapitaldelen av en betalning","arguments":["Ränta","Period","Perioder","Nuvärde","Framtida värde","Typ"]},{"base":"PRODUCT","name":"PRODUKT"},{"base":"PV","name":"NUVÄRDE","description":"Returnerar nuvärdet av en investering","arguments":["Ränta","Perioder","Betalning","Framtida värde","Typ"]},{"base":"QUARTILE","name":"KVARTIL","description":"Returnerar den interpolerade kvartilen av datasetet (inklusive median)","arguments":["intervall","kvartil"]},{"base":"QUARTILE.EXC","name":"KVARTIL.EXK","description":"Returnerar den interpolerade kvartilen av datasetet (exklusive median)","arguments":["intervall","kvartil"]},{"base":"QUARTILE.INC","name":"KVARTIL.INK","description":"Returnerar den interpolerade kvartilen av datasetet (inklusive median)","arguments":["intervall","kvartil"]},{"base":"RADIANS","name":"RADIANER","description":"Konverterar grader till radianer","arguments":["Grader"]},{"base":"RAND","name":"SLUMP"},{"base":"RANDBETWEEN","name":"SLUMP.MELLAN","arguments":["min","max"]},{"base":"RANK","name":"RANG","arguments":["Värde","Källa","Ordning"]},{"base":"RATE","name":"RÄNTA","description":"Returnerar räntan för ett lån","arguments":["Perioder","Betalning","Nuvärde","Framtida värde","Typ"]},{"base":"REAL","name":"REAL","description":"Returnerar den reella delen av ett komplext tal"},{"base":"RECTANGULAR","name":"RECTANGULAR","description":"Konverterar ett komplext tal i polär form till rektangulär form","arguments":["r","θ i radianer"]},{"base":"REGEXEXTRACT","name":"REGEXEXTRACT","description":"Extrahera text med hjälp av ett reguljärt uttryck","arguments":["text","mönster","returläge","skiftlägesokänslig"]},{"base":"REGEXREPLACE","name":"REGEXREPLACE","description":"Ersätt text i en sträng med hjälp av ett reguljärt uttryck","arguments":["text","mönster","ersättning","förekomst","skiftlägesokänslig"]},{"base":"REGEXTEST","name":"REGEXTEST","description":"Matcha text mot ett reguljärt uttryck","arguments":["text","mönster","skiftlägesokänslig"]},{"base":"RIGHT","name":"HÖGER","arguments":["sträng","antal"]},{"base":"ROUND","name":"AVRUNDA"},{"base":"ROUNDDOWN","name":"AVRUNDA.NEDÅT"},{"base":"ROUNDUP","name":"AVRUNDA.UPPÅT"},{"base":"ROW","name":"RAD","arguments":["referens"]},{"base":"ROWS","name":"RADER","arguments":["referens"]},{"base":"SEARCH","name":"SÖK","description":"Hitta en sträng (nål) i en annan sträng (höstack). Skiftlägesokänslig.","arguments":["Nål","Höstack","Start"]},{"base":"SEQUENCE","name":"SEQUENCE","arguments":["rader","kolumner","start","steg"]},{"base":"SIGN","name":"TECKEN"},{"base":"SIMPLIFY","name":"SIMPLIFY","arguments":["värde","signifikanta siffror"]},{"base":"SIN","name":"SIN","arguments":["vinkel i radianer"]},{"base":"SINH","name":"SINH","arguments":["tal"]},{"base":"SLOPE","name":"LUTNING","arguments":["kända_y","kända_x"]},{"base":"SMALL","name":"MINSTA","description":"Returnerar det n:te numeriska värdet från data i stigande ordning","arguments":["värden","index"]},{"base":"SORT","name":"SORT","arguments":["värden"]},{"base":"SPARKLINE.COLUMN","name":"SPARKLINE.COLUMN","arguments":["data","färg","negativ färg"]},{"base":"SPARKLINE.LINE","name":"SPARKLINE.LINE","arguments":["data","färg","linjebredd"]},{"base":"SQRT","name":"ROT","description":"Returnerar kvadratroten av argumentet"},{"base":"STDEV","name":"STDAV","description":"Returnerar standardavvikelsen för en uppsättning värden motsvarande ett stickprov från en population","arguments":["data"]},{"base":"STDEV.P","name":"STDAV.P","description":"Returnerar standardavvikelsen för en uppsättning värden motsvarande en population","arguments":["data"]},{"base":"STDEV.S","name":"STDAV.S","description":"Returnerar standardavvikelsen för en uppsättning värden motsvarande ett stickprov från en population","arguments":["data"]},{"base":"STDEVA","name":"STDEVA","description":"Returnerar standardavvikelsen för en uppsättning värden motsvarande ett stickprov från en population","arguments":["data"]},{"base":"STDEVPA","name":"STDEVPA","description":"Returnerar standardavvikelsen för en uppsättning värden motsvarande en population","arguments":["data"]},{"base":"SUBSTITUTE","name":"BYT.UT","arguments":["text","sök","ersättning","index"]},{"base":"SUBTOTAL","name":"DELSUMMA","arguments":["typ","intervall"]},{"base":"SUM","name":"SUMMA","description":"Adderar argument och intervall","arguments":["värden eller intervall"]},{"base":"SUMIF","name":"SUMMA.OM","arguments":["intervall","villkor"]},{"base":"SUMIFS","name":"SUMMA.OMF","arguments":["värdeintervall","villkorsintervall","villkor","villkorsintervall","villkor"]},{"base":"SUMPRODUCT","name":"PRODUKTSUMMA","description":"Returnerar summan av parvisa produkter av två eller fler intervall"},{"base":"SUMSQ","name":"KVADRATSUMMA","description":"Returnerar summan av kvadraterna av alla argument","arguments":["värden eller intervall"]},{"base":"TAN","name":"TAN","arguments":["vinkel i radianer"]},{"base":"TANH","name":"TANH","arguments":["tal"]},{"base":"TEXT","name":"TEXT","arguments":["värde","talformat"]},{"base":"TODAY","name":"IDAG","description":"Returnerar aktuell dag"},{"base":"TRANSPOSE","name":"TRANSPONERA","description":"Returnerar transponatet av inmatningsmatrisen","arguments":["matris"]},{"base":"TRUNC","name":"AVKORTA"},{"base":"UPPER","name":"VERSALER","description":"Konverterar text till versaler","arguments":["text"]},{"base":"VALUE","name":"TEXTNUM","arguments":["text"]},{"base":"VAR","name":"VARIANS","description":"Returnerar variansen för en uppsättning värden motsvarande ett stickprov från en population","arguments":["data"]},{"base":"VAR.P","name":"VARIANS.P","description":"Returnerar variansen för en uppsättning värden motsvarande en population","arguments":["data"]},{"base":"VAR.S","name":"VARIANS.S","description":"Returnerar variansen för en uppsättning värden motsvarande ett stickprov från en population","arguments":["data"]},{"base":"VLOOKUP","name":"LETARAD","arguments":["Sökvärde","Tabell","Resultatindex","Inexakt"]},{"base":"XIRR","name":"XIRR","description":"Returnerar den interna avkastningsgraden för en icke-periodisk ström av betalningar","arguments":["Värden","Datum","Gissning"]},{"base":"XLOOKUP","name":"XLETAUPP","arguments":["Sökvärde","Sökmatris","Returmatris","Ej funnet","Matchningsläge","Sökläge"]},{"base":"XNPV","name":"XNUVÄRDE","description":"Returnerar NPV för en icke-periodisk ström av betalningar vid en given ränta","arguments":["Diskonteringsränta","Värden","Datum"]},{"base":"YEAR","name":"ÅR","description":"Returnerar år från datum","arguments":["datum"]},{"base":"YEARFRAC","name":"ÅRDEL","description":"Returnerar bråkdelen av ett år mellan två datum","arguments":["Start","Slut","Basis"]},{"base":"Z.TEST","name":"Z.TEST","arguments":["Array","x","Sigma"]}]};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trebco/treb",
3
- "version": "31.8.2",
3
+ "version": "32.1.1",
4
4
  "license": "LGPL-3.0-or-later",
5
5
  "homepage": "https://treb.app",
6
6
  "repository": {
@@ -16,7 +16,7 @@
16
16
  "@types/uzip": "^0.20201231.0",
17
17
  "base64-js": "^1.5.1",
18
18
  "cssnano": "^7.0.4",
19
- "esbuild": "^0.23.1",
19
+ "esbuild": "^0.24.0",
20
20
  "eslint": "^9.9.1",
21
21
  "fast-xml-parser": "^4.0.7",
22
22
  "html-minifier-terser": "^7.2.0",
@@ -85,6 +85,11 @@ export interface ExtendedUnion {
85
85
  key?: string;
86
86
  }
87
87
 
88
+ export interface FunctionUnion {
89
+ type: ValueType.function,
90
+ value: unknown;
91
+ }
92
+
88
93
  /** potentially recursive structure */
89
94
  export interface ArrayUnion {
90
95
  type: ValueType.array;
@@ -102,6 +107,7 @@ export type UnionValue
102
107
  | FormulaUnion
103
108
  | UndefinedUnion
104
109
  | BooleanUnion
110
+ | FunctionUnion
105
111
  | ErrorUnion
106
112
  ;
107
113
 
@@ -84,6 +84,11 @@ export const IsDimensionedQuantity = (value: unknown): value is DimensionedQuant
84
84
  && (typeof (value as DimensionedQuantity).unit === 'string');
85
85
  };
86
86
 
87
+ /** temp until we have a solid type */
88
+ export const IsFunctionType = (value: unknown) => {
89
+ return (typeof value === 'object' && (value as { type: string }).type === 'function');
90
+ };
91
+
87
92
  /**
88
93
  * this is the list of value types. internally, we use an enum. I don't
89
94
  * want to change that, at least not at the moment, but that presents a
@@ -102,6 +107,7 @@ export const ValueTypeList = [
102
107
  'number',
103
108
  'boolean',
104
109
  'object',
110
+ 'function',
105
111
  'error',
106
112
  'complex',
107
113
  'array',
@@ -123,6 +129,7 @@ export type SerializedValueType = // typeof ValueTypeList[number];
123
129
  'number' |
124
130
  'boolean' |
125
131
  'object' |
132
+ 'function' |
126
133
  'error' |
127
134
  'complex' |
128
135
  'array' |
@@ -174,6 +181,9 @@ export enum ValueType {
174
181
  // adding DQ to union
175
182
  dimensioned_quantity = 9,
176
183
 
184
+ // new for lambdas
185
+ function = 10,
186
+
177
187
  }
178
188
 
179
189
  /** @internal */
@@ -194,6 +204,9 @@ export const GetValueType = (value: unknown): ValueType => {
194
204
  if (value === null) {
195
205
  return ValueType.undefined;
196
206
  }
207
+ else if (IsFunctionType(value)) {
208
+ return ValueType.function;
209
+ }
197
210
  else if (IsComplex(value)) {
198
211
  return ValueType.complex;
199
212
  }
@@ -47,6 +47,7 @@ import { StatisticsFunctionLibrary, StatisticsFunctionAliases } from './function
47
47
  import { ComplexFunctionLibrary } from './functions/complex-functions';
48
48
  import { MatrixFunctionLibrary } from './functions/matrix-functions';
49
49
  import { RegexFunctionLibrary } from './functions/regex-functions';
50
+ import { LambdaFunctionLibrary } from './functions/lambda-functions';
50
51
 
51
52
  import { Variance } from './functions/statistics-functions';
52
53
 
@@ -240,6 +241,7 @@ export class Calculator extends Graph {
240
241
  ComplexFunctionLibrary,
241
242
  MatrixFunctionLibrary,
242
243
  RegexFunctionLibrary,
244
+ LambdaFunctionLibrary,
243
245
  );
244
246
 
245
247
  // aliases
@@ -1431,6 +1433,7 @@ export class Calculator extends Graph {
1431
1433
  switch (v.type) {
1432
1434
  case ValueType.object:
1433
1435
  case ValueType.array:
1436
+ case ValueType.function:
1434
1437
  break;
1435
1438
  default:
1436
1439
  cell.SetCalculatedValue(v.value, v.type);
@@ -1499,6 +1502,7 @@ export class Calculator extends Graph {
1499
1502
  switch (indexed_value.type) {
1500
1503
  case ValueType.array:
1501
1504
  case ValueType.object:
1505
+ case ValueType.function:
1502
1506
  cells.data[row + area.start.row][column + area.start.column].SetCalculatedValue(undefined); // error?
1503
1507
  break;
1504
1508
 
@@ -1538,7 +1542,7 @@ export class Calculator extends Graph {
1538
1542
 
1539
1543
  let applied: UnionValue = { ...value };
1540
1544
 
1541
- if (applied.type === ValueType.object) {
1545
+ if (applied.type === ValueType.object || applied.type === ValueType.function) {
1542
1546
  applied = { type: ValueType.undefined, value: undefined };
1543
1547
  }
1544
1548
 
@@ -2685,6 +2689,10 @@ export class Calculator extends Graph {
2685
2689
  *
2686
2690
  * this might cause issues if we ever try to actually resolve from the
2687
2691
  * sheet name, though, so (...)
2692
+ *
2693
+ *
2694
+ * Q: why does this not use the parser Walk/Walk2 routine?
2695
+ *
2688
2696
  */
2689
2697
  protected RebuildDependencies(
2690
2698
  unit: ExpressionUnit,
@@ -2879,6 +2887,15 @@ export class Calculator extends Graph {
2879
2887
  this.RebuildDependencies(element, relative_sheet_id, relative_sheet_name, dependencies, context_address));//, sheet_name_map));
2880
2888
  break;
2881
2889
 
2890
+ case 'implicit-call':
2891
+ {
2892
+ for (const arg of unit.args) {
2893
+ this.RebuildDependencies(arg, relative_sheet_id, relative_sheet_name, dependencies, context_address);
2894
+ }
2895
+ this.RebuildDependencies(unit.call, relative_sheet_id, relative_sheet_name, dependencies, context_address);
2896
+ }
2897
+ break;
2898
+
2882
2899
  case 'call':
2883
2900
 
2884
2901
  // this is where we diverge. if there's a known function that has
@@ -20,6 +20,7 @@
20
20
  */
21
21
 
22
22
  import type { RenderFunction, ClickFunction, UnionValue, ICellAddress, IArea } from 'treb-base-types';
23
+ import type { ExpressionUnit } from 'treb-parser';
23
24
 
24
25
  /**
25
26
  * FIXME: possible to add stuff in here if we need it
@@ -46,6 +47,9 @@ export interface ArgumentDescriptor {
46
47
  description?: string;
47
48
  default?: number|string|boolean;
48
49
 
50
+ /** @internal TODO: rename */
51
+ passthrough?: boolean;
52
+
49
53
  // moved from function arrays:
50
54
 
51
55
  /**
@@ -73,7 +77,9 @@ export interface ArgumentDescriptor {
73
77
 
74
78
  /**
75
79
  * this argument repeasts. this has no impact on the function descriptor
76
- * but it's useful to know for clients.
80
+ * but it's useful to know for clients. UPDATE: going to use this for
81
+ * let, which repeats arguments at the front. not sure what that's going
82
+ * to do to clients. maybe it will just magically work!
77
83
  */
78
84
  repeat?: boolean;
79
85
 
@@ -99,6 +105,28 @@ export interface ArgumentDescriptor {
99
105
 
100
106
  }
101
107
 
108
+ /**
109
+ * @internal
110
+ */
111
+ export interface ContextResult {
112
+
113
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
114
+ context: Record<string, ExpressionUnit>;
115
+
116
+ /**
117
+ * rewrite args
118
+ */
119
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
120
+ args: any[];
121
+
122
+ /** possibly rewrite argument descriptors, not required */
123
+ argument_descriptors?: ArgumentDescriptor[];
124
+
125
+ }
126
+
127
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
128
+ export type FunctionImplementation = (this: FunctionContext|undefined, ...args: any[]) => UnionValue;
129
+
102
130
  /**
103
131
  * merging the old function descriptor and decorated function types, since
104
132
  * there's a good deal of overlap and we spend a lot of effort keeping them
@@ -140,8 +168,7 @@ export interface CompositeFunctionDescriptor {
140
168
  * if your function is defined as a function (i.e. not an arrow function).
141
169
  *
142
170
  */
143
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
144
- fn: (this: FunctionContext|undefined, ...args: any[]) => UnionValue;
171
+ fn: FunctionImplementation;
145
172
 
146
173
  /**
147
174
  * limited visibility
@@ -196,6 +223,18 @@ export interface CompositeFunctionDescriptor {
196
223
  */
197
224
  unrolled?: boolean;
198
225
 
226
+ /**
227
+ * this is new: custom binding context for lambda functions (lambda, let,
228
+ * and maybe others?) still working out the semantics of this.
229
+ *
230
+ * @internal
231
+ */
232
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
233
+ create_binding_context?: (context: {
234
+ args: ExpressionUnit[];
235
+ descriptors: ArgumentDescriptor[];
236
+ }) => ContextResult | undefined;
237
+
199
238
  }
200
239
 
201
240
  export interface FunctionMap {
@@ -30,11 +30,13 @@ import type { Cell, ICellAddress,
30
30
  IArea} from 'treb-base-types';
31
31
  import { ValueType, GetValueType, Area } from 'treb-base-types';
32
32
  import type { Parser, ExpressionUnit, UnitBinary, UnitIdentifier,
33
- UnitGroup, UnitUnary, UnitAddress, UnitRange, UnitCall, UnitDimensionedQuantity, UnitStructuredReference } from 'treb-parser';
33
+ UnitGroup, UnitUnary, UnitAddress, UnitRange, UnitCall, UnitDimensionedQuantity, UnitStructuredReference,
34
+ UnitImplicitCall} from 'treb-parser';
34
35
  import type { DataModel, MacroFunction, Sheet } from 'treb-data-model';
35
- import { NameError, ReferenceError, ExpressionError, UnknownError, SpillError, ValueError } from './function-error';
36
+ import { NameError, ReferenceError, ExpressionError, UnknownError, SpillError, ValueError, ArgumentError } from './function-error';
36
37
 
37
38
  import * as Primitives from './primitives';
39
+ import type { ContextResult } from './descriptors';
38
40
 
39
41
  //////////
40
42
 
@@ -82,10 +84,17 @@ export interface ReferenceMetadata {
82
84
  format?: string;
83
85
  }
84
86
 
87
+ export type BindingFrame = Record<string, ExpressionUnit>; // FIXME (type?)
88
+ export type PositionalFrame = ExpressionUnit[];
89
+
85
90
  export interface CalculationContext {
86
91
  address: ICellAddress;
87
92
  area?: IArea;
88
93
  volatile: boolean;
94
+
95
+ /** new for lambdas */
96
+ bindings: BindingFrame[];
97
+
89
98
  }
90
99
 
91
100
  export class ExpressionCalculator {
@@ -93,6 +102,7 @@ export class ExpressionCalculator {
93
102
  public context: CalculationContext = {
94
103
  address: { row: -1, column: -1 },
95
104
  volatile: false,
105
+ bindings: [],
96
106
  };
97
107
 
98
108
  // --- public API -----------------------------------------------------------
@@ -438,6 +448,93 @@ export class ExpressionCalculator {
438
448
 
439
449
  }
440
450
 
451
+ /**
452
+ * this method can take a `call` type if it looked like a call at
453
+ * the parsing stage, it's a simple translation between the two
454
+ */
455
+ protected ImplicitCall(): (expr: UnitImplicitCall|UnitCall) => UnionValue {
456
+ return (expr: UnitImplicitCall|UnitCall) => {
457
+
458
+ if (expr.type === 'call') {
459
+ expr = {
460
+ type: 'implicit-call',
461
+ args: expr.args,
462
+ call: {
463
+ type: 'identifier',
464
+ name: expr.name,
465
+ position: expr.position,
466
+ id: 0,
467
+ },
468
+ position: expr.position,
469
+ id: 0,
470
+ };
471
+ }
472
+
473
+ const result = this.CalculateExpression(expr.call as ExtendedExpressionUnit);
474
+
475
+ if (result.type === ValueType.function) {
476
+
477
+ const value = result.value as {
478
+ bindings: ExpressionUnit[];
479
+ func: ExpressionUnit|undefined;
480
+ };
481
+
482
+ if (!value.func || !value.bindings) {
483
+ return ExpressionError();
484
+ }
485
+
486
+ // let frame = value.bindings(expr.args);
487
+
488
+ const frame: BindingFrame = {};
489
+
490
+ for (let i = 0; i < value.bindings.length; i++) {
491
+ const name = value.bindings[i];
492
+ if (name?.type === 'identifier') {
493
+ frame[name.name.toUpperCase()] = expr.args[i] || { type: 'missing' };
494
+ }
495
+ else {
496
+ // should not happen, error
497
+ return ExpressionError();
498
+ }
499
+ }
500
+
501
+ // frame = this.NormalizeBindings(frame); // inline
502
+
503
+ const munged = JSON.parse(JSON.stringify(value.func));
504
+
505
+ this.parser.Walk2(munged, (unit: ExpressionUnit) => {
506
+ if (unit.type === 'identifier') {
507
+ const upper_case = unit.name.toUpperCase();
508
+ const binding = frame[upper_case];
509
+ if (binding) {
510
+ return JSON.parse(JSON.stringify(binding));
511
+ }
512
+ }
513
+ return true;
514
+ });
515
+
516
+ // console.info({frame, func, munged});
517
+
518
+ // const exec_result = this.CalculateExpression(munged as ExtendedExpressionUnit);
519
+ // return exec_result || ExpressionError();
520
+
521
+ return this.CalculateExpression(munged as ExtendedExpressionUnit);
522
+
523
+ }
524
+
525
+ return ExpressionError();
526
+
527
+ };
528
+ }
529
+
530
+ protected NormalizeBindings(context: BindingFrame) {
531
+ const frame: Record<string, ExpressionUnit> = {};
532
+ for (const [key, value] of Object.entries(context)) {
533
+ frame[key.toUpperCase()] = value;
534
+ }
535
+ return frame;
536
+ }
537
+
441
538
  /**
442
539
  * excute a function call
443
540
  */
@@ -451,6 +548,18 @@ export class ExpressionCalculator {
451
548
 
452
549
  if (!func) {
453
550
 
551
+ const upper_case = outer.name.toUpperCase();
552
+
553
+ const binding = this.LookupBinding(upper_case);
554
+ if (binding) {
555
+ return this.ImplicitCall();
556
+ }
557
+
558
+ const named = this.data_model.GetName(upper_case, this.context.address.sheet_id || 0);
559
+ if (named) {
560
+ return this.ImplicitCall();
561
+ }
562
+
454
563
  if (process.env.NODE_ENV !== 'production') {
455
564
  console.info('(dev) missing function', outer.name);
456
565
  }
@@ -474,9 +583,36 @@ export class ExpressionCalculator {
474
583
  let skip_argument_index = -1;
475
584
  let argument_error: UnionValue|undefined;
476
585
 
477
- const argument_descriptors = func.arguments || []; // map
586
+ // possibly create a binding frame. if we do that we may need
587
+ // to adjust the arguments as well (and the descriptors)
588
+
589
+ let args = expr.args;
590
+ let argument_descriptors = func.arguments || []; // map
591
+
592
+ let binding: ContextResult|undefined;
593
+ if (func.create_binding_context) {
478
594
 
479
- const mapped_args = expr.args.map((arg, arg_index) => {
595
+ // if this does not return a binding frame, it's an error.
596
+
597
+ binding = func.create_binding_context.call(0, {
598
+ args: expr.args,
599
+ descriptors: argument_descriptors,
600
+ });
601
+
602
+ if (binding) {
603
+ args = binding.args;
604
+ if (binding.argument_descriptors) {
605
+ argument_descriptors = binding.argument_descriptors;
606
+ }
607
+ this.context.bindings.unshift(this.NormalizeBindings(binding.context));
608
+ }
609
+ else {
610
+ argument_error = ArgumentError();
611
+ }
612
+
613
+ }
614
+
615
+ const mapped_args = args.map((arg, arg_index) => {
480
616
 
481
617
  // short circuit
482
618
  if (argument_error) {
@@ -485,8 +621,18 @@ export class ExpressionCalculator {
485
621
 
486
622
  // get descriptor. if the number of arguments exceeds
487
623
  // the number of descriptors, recycle the last one
624
+
625
+ // FIXME: we have a repeat flag, so we should repeat the
626
+ // correct argument(s). I guess we could default to this
627
+ // behavior.
628
+
488
629
  const descriptor = argument_descriptors[Math.min(arg_index, argument_descriptors.length - 1)] || {};
489
-
630
+
631
+ // new for lambdas
632
+ if (descriptor.passthrough) {
633
+ return arg;
634
+ }
635
+
490
636
  // if function, wrong branch
491
637
  if (arg_index === skip_argument_index) {
492
638
  return descriptor.boxed ? { type: ValueType.undefined } : undefined;
@@ -559,6 +705,10 @@ export class ExpressionCalculator {
559
705
 
560
706
  });
561
707
 
708
+ if (binding) {
709
+ this.context.bindings.shift();
710
+ }
711
+
562
712
  if (argument_error) {
563
713
  return argument_error;
564
714
  }
@@ -1025,8 +1175,13 @@ export class ExpressionCalculator {
1025
1175
 
1026
1176
  return () => {
1027
1177
 
1028
- const named = this.data_model.GetName(upper_case, this.context.address.sheet_id || 0);
1178
+ const binding = this.LookupBinding(upper_case);
1179
+ if (binding) {
1180
+ return this.CalculateExpression(binding as ExtendedExpressionUnit);
1181
+ }
1029
1182
 
1183
+ const named = this.data_model.GetName(upper_case, this.context.address.sheet_id || 0);
1184
+
1030
1185
  switch (named?.type) {
1031
1186
  case 'range':
1032
1187
  if (named.area.count === 1) {
@@ -1046,6 +1201,23 @@ export class ExpressionCalculator {
1046
1201
 
1047
1202
  }
1048
1203
 
1204
+ /**
1205
+ * look up an identifier in any binding frames. we do LIFO binding.
1206
+ *
1207
+ * @param name
1208
+ * @returns
1209
+ */
1210
+ protected LookupBinding(name: string) {
1211
+ name = name.toUpperCase();
1212
+ for (const frame of this.context.bindings) {
1213
+ const value = frame[name];
1214
+ if (value) {
1215
+ return value;
1216
+ }
1217
+ }
1218
+ return undefined;
1219
+ }
1220
+
1049
1221
  protected GroupExpression(x: UnitGroup): (expr: UnitGroup) => UnionValue /*UnionOrArray*/ {
1050
1222
 
1051
1223
  // a group is an expression in parentheses, either explicit
@@ -1075,6 +1247,10 @@ export class ExpressionCalculator {
1075
1247
  }
1076
1248
 
1077
1249
  switch (expr.type){
1250
+
1251
+ case 'implicit-call':
1252
+ return (expr.fn = this.ImplicitCall())(expr);
1253
+
1078
1254
  case 'call':
1079
1255
  {
1080
1256
  const macro = this.data_model.macro_functions.get(expr.name.toUpperCase());