formula

package
v0.228.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 20, 2026 License: BSD-3-Clause Imports: 4 Imported by: 0

Documentation

Overview

Package formula is the spreadsheet formula engine behind the toolkit's Spreadsheet widget: it lexes, parses and evaluates "=" expressions over an A1-addressed grid of cells, and maintains a dependency graph so an edit recomputes exactly the cells that (transitively) depend on it, with cycle detection that yields a #CIRC! error value instead of looping forever.

The public surface is deliberately small: a Model owns the grid, SetCell feeds it raw user input (a literal or a leading-"=" formula), and Display / Get read back the computed result. Everything else (the lexer, the parser, the AST and the evaluator) is unexported so the engine can evolve without widening the widget's contract.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ColumnName

func ColumnName(col int) string

ColumnName is the bijective base-26 letter label for a 0-based column index: 0 -> "A", 25 -> "Z", 26 -> "AA", 27 -> "AB". It is the column-header label the Spreadsheet widget paints.

func Parse

func Parse(s string) (*node, error)

Parse lexes and parses a formula body into an AST, or returns errSyntax. The whole input must be consumed: trailing tokens ("1 2") are a syntax error.

Types

type Env

type Env interface {
	Get(r Ref) Value
	InBounds(r Ref) bool
}

Env is the sheet an expression reads cell values from. Get returns the current value of an in-bounds cell (a blank for a never-written one); InBounds reports whether a ref lies inside the grid, so an out-of-range reference or range corner can be turned into #REF!.

type ErrKind

type ErrKind int

ErrKind enumerates the spreadsheet error values. Their String forms are the exact "#...!" tokens a cell renders and the ones tests assert against.

const (
	// ErrNone is the absence of an error; never stored in a KindError Value.
	ErrNone ErrKind = iota
	// ErrDiv0 is #DIV/0!: a division by zero, or an average of no numbers.
	ErrDiv0
	// ErrRef is #REF!: a reference (or a range corner) outside the sheet.
	ErrRef
	// ErrName is #NAME?: an unknown function, an unknown bare identifier, or a
	// formula the engine cannot parse.
	ErrName
	// ErrCirc is #CIRC!: a cell that (transitively) references itself.
	ErrCirc
	// ErrValue is #VALUE!: a type mismatch (text where a number is needed), a
	// bare range in scalar position, or a function called with the wrong arity.
	ErrValue
	// ErrNum is #NUM!: a numeric result that is NaN or infinite.
	ErrNum
)

func (ErrKind) String

func (e ErrKind) String() string

String is the "#...!" token an ErrKind renders as.

type Kind

type Kind int

Kind is the dynamic type of a Value: a number, a text string, an error, or the blank a never-written (or cleared) cell holds.

const (
	// KindBlank is an empty cell: it reads as 0 in arithmetic and "" as text.
	KindBlank Kind = iota
	// KindNumber is a floating-point number.
	KindNumber
	// KindText is a string literal (or a non-numeric cell value).
	KindText
	// KindError is one of the ErrKind sentinels (#DIV/0!, #REF!, ...).
	KindError
)

type Model

type Model struct {
	// contains filtered or unexported fields
}

Model is an A1-addressed grid of cells and the formula engine over it. A cell holds raw user input — a literal (number or text) or a leading-"=" formula — and a computed Value. SetCell recomputes every formula cell in dependency order (with #CIRC! for cycles); Get and Display read the results back.

The zero Model is not usable; build one with NewModel.

func NewModel

func NewModel(cols, rows int) *Model

NewModel builds an empty cols x rows sheet. Negative dimensions clamp to 0.

func (*Model) Cols

func (m *Model) Cols() int

Cols reports the sheet's column count.

func (*Model) Display

func (m *Model) Display(r Ref) string

Display is the string cell r renders — the computed value's Display form.

func (*Model) Get

func (m *Model) Get(r Ref) Value

Get returns the computed value of r: the cell's value, or a blank for an empty (or out-of-bounds) cell.

func (*Model) InBounds

func (m *Model) InBounds(r Ref) bool

InBounds reports whether r lies inside the sheet.

func (*Model) Raw

func (m *Model) Raw(r Ref) string

Raw returns the raw text stored in r (what an editor re-opens), or "" when the cell is empty.

func (*Model) Rows

func (m *Model) Rows() int

Rows reports the sheet's row count.

func (*Model) SetCell

func (m *Model) SetCell(r Ref, raw string)

SetCell stores raw as the contents of cell r and recomputes the sheet. An empty raw clears the cell. A leading '=' marks a formula (parsed now, with a parse failure stored as a #NAME? value); anything else is a literal, kept as a number when it parses as one and as text otherwise. Setting an out-of-bounds cell is a no-op.

type Ref

type Ref struct {
	Col, Row int
}

Ref is a single cell address, held as 0-based column and row indices so it indexes the grid directly. A1 is Ref{Col: 0, Row: 0}; B3 is Ref{Col: 1, Row: 2}. The A1 spelling (letters then a 1-based row) is only a surface form, produced by A1 and consumed by ParseRef.

func ParseRef

func ParseRef(s string) (Ref, bool)

ParseRef parses an A1 spelling ("A1", "AB10") into a Ref. ok is false for any string that is not letters-then-digits with a positive row (so "A0", "1", "A", "A1B" and "" all fail). The caller has already upper-cased the text.

func (Ref) A1

func (r Ref) A1() string

A1 is the spreadsheet spelling of the reference: the column letters followed by the 1-based row number (Ref{0,0} -> "A1", Ref{27,9} -> "AB10").

type Value

type Value struct {
	Kind Kind
	Num  float64
	Text string
	Err  ErrKind
}

Value is one evaluated result: a number, a text string, a blank, or an error. Only the field named by Kind is meaningful; the others hold their zero value.

func Blank

func Blank() Value

Blank builds the empty-cell Value.

func Error

func Error(e ErrKind) Value

Error builds an error Value carrying e.

func Number

func Number(n float64) Value

Number builds a numeric Value.

func TextValue

func TextValue(s string) Value

TextValue builds a text Value.

func (Value) Display

func (v Value) Display() string

Display is the string a cell renders for v: the trimmed number, the text verbatim, the "#...!" token for an error, or "" for a blank.

func (Value) IsError

func (v Value) IsError() bool

IsError reports whether v is an error value — the check the widget uses to tint an errored cell.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL