Documentation
¶
Overview ¶
Package filo provides Marshal and Unmarshal functions for converting between Go values and Filo Value types.
Marshal converts any Go value supported by Filo (bool, numbers, string, slices, structs, maps) into a Filo Value.
Unmarshal converts a Filo Value into a Go value. The target must be a pointer to any Filo-supported type.
Struct fields use the "filo" tag to specify the field name. If no tag is present, the lowercased field name is used. Fields with tag "-" are skipped.
Example:
type Person struct {
Name string `filo:"name"`
Age int `filo:"age"`
}
p := Person{Name: "Alice", Age: 30}
val, err := filo.Marshal(p)
// val is a list of tuples: [("name", "Alice"), ("age", 30)]
var p2 Person
err = filo.Unmarshal(val, &p2)
// p2 is now {Name: "Alice", Age: 30}
Package filo provides Lisp-style formatting for Filo code.
The formatting follows common Lisp conventions for readability:
- Short expressions stay on one line: (+ 1 2)
- Function arguments align vertically when multiline
- Special forms (let, if, fn, def) have specific indentation rules
- Strings with escapes are preserved exactly: "test \" test"
- Comments and blank lines are preserved
Example (Do) ¶
// The 'do' special form evaluates multiple expressions in sequence
// and returns the value of the last one.
// Useful for side effects or grouping commands.
eng := NewEngine()
script := `
(do
(def x 10)
(def y 20)
(+ x y))`
val, _, _ := eng.RunScript(context.Background(), script, nil, EvalConfig{})
fmt.Printf("Result: %v\n", val.Num)
Output: Result: 30
Example (TypeOf) ¶
// 'type-of' returns the type of a value as a string.
// Possible values: "number", "string", "bool", "list", "tuple", "map", "func".
eng := NewEngine()
script := `
(let ((n 42)
(s "hello"))
(list (type-of n) (type-of s)))`
val, _, _ := eng.RunScript(context.Background(), script, nil, EvalConfig{})
// Manually inspect list to print
l, _ := val.AsList()
fmt.Printf("Types: %s, %s\n", l[0].Str, l[1].Str)
Output: Types: number, string
Index ¶
- Variables
- func Format(src string) (string, error)
- func FormatAST(node Node, cfg FormatConfig) (string, error)
- func FormatValue(v Value) string
- func FormatValueIndent(v Value, prefix, indent string) string
- func FormatWithConfig(src string, cfg FormatConfig) (string, error)
- func Marshal(v any) (string, error)
- func MarshalIndent(v any, prefix, indent string) (string, error)
- func MarshalWithOptions(v any, opts MarshalOptions) (string, error)
- func Unmarshal(data string, target any) error
- func UnmarshalFromValue(val Value, target any) error
- type BoolLit
- type Builtin
- type Engine
- func (e *Engine) Compile(src string) (*Program, error)
- func (e *Engine) CompileAST(ast Node) (*Program, error)
- func (e *Engine) ExecuteAST(ctx context.Context, ast Node, globals map[string]Value, cfg EvalConfig) (result Value, newGlobals map[string]Value, err error)
- func (e *Engine) MustRegisterBuiltin(name string, fn Builtin)
- func (e *Engine) RegisterBuiltin(name string, fn Builtin) error
- func (e *Engine) RunScript(ctx context.Context, src string, globals map[string]Value, cfg EvalConfig) (result Value, newGlobals map[string]Value, err error)
- type EvalConfig
- type Filo
- func (f *Filo) CallFunction(name string, args ...any) (Value, error)
- func (f *Filo) CallFunctionString(name string, fallback string, args ...any) string
- func (f *Filo) Close()
- func (f *Filo) DoString(filoScript string) error
- func (f *Filo) Execute(script *Script, overrideGlobals map[string]Value) error
- func (f *Filo) GetBool(vGlobal string) (bool, error)
- func (f *Filo) GetEngine() *Engine
- func (f *Filo) GetInt(vGlobal string) (int, error)
- func (f *Filo) GetMap(vGlobal string) (map[string]string, error)
- func (f *Filo) GetMapOfLists(vGlobal string) (map[string][]string, error)
- func (f *Filo) GetString(vGlobal string) (string, error)
- func (f *Filo) GetTable(vGlobal string) ([]string, error)
- func (f *Filo) HasFunction(name string) bool
- func (f *Filo) MustGetBool(vGlobal string) bool
- func (f *Filo) MustGetInt(vGlobal string) int
- func (f *Filo) MustGetMap(vGlobal string) map[string]string
- func (f *Filo) MustGetMapOfLists(vGlobal string) map[string][]string
- func (f *Filo) MustGetString(vGlobal string) string
- func (f *Filo) MustGetTable(vGlobal string) []string
- func (f *Filo) RegisterBuiltin(name string, fn Builtin) error
- func (f *Filo) SetGlobal(name string, value any)
- func (f *Filo) SetGlobalMapOfLists(name string, m map[string][]string)
- type FormatConfig
- type Frame
- type Func
- type GlobalEnv
- type Kind
- type List
- type MarshalOptions
- type Node
- type NumberLit
- type ParseError
- type Program
- type ResolvedBuiltin
- type ResolvedGlobal
- type ResolvedSymbol
- type Scope
- type Script
- type StringLit
- type Symbol
- type SymbolTable
- type Value
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrorFunctionNotFound = errors.New("function not found") ErrorNotAllowedType = errors.New("not allowed return type") )
Functions ¶
func Format ¶ added in v0.0.5
Format formats Filo source code with Lisp-style indentation. It preserves comments and blank lines.
func FormatAST ¶ added in v0.0.5
func FormatAST(node Node, cfg FormatConfig) (string, error)
FormatAST formatting an AST node back to string. This is used when the AST has been modified (e.g. by constant folding) and we can't use the token-based formatter.
func FormatValue ¶ added in v0.0.5
FormatValue formats a Filo Value as a readable string.
func FormatValueIndent ¶ added in v0.0.5
FormatValueIndent formats a Value with prefix and indent strings. Similar to json.MarshalIndent behavior.
func FormatWithConfig ¶ added in v0.0.5
func FormatWithConfig(src string, cfg FormatConfig) (string, error)
FormatWithConfig formats Filo source with custom configuration. Comments and intentional blank lines are preserved.
func Marshal ¶ added in v0.0.5
Marshal converts a Go value to a compact Filo string. To modify the formatting, use MarshalIndent.
func MarshalIndent ¶ added in v0.0.5
MarshalIndent converts a Go value to an indented Filo string. The prefix is prepended to each line (including the first), and indent is added per nesting level.
This is similar to json.MarshalIndent but produces Filo syntax.
func MarshalWithOptions ¶ added in v0.0.5
func MarshalWithOptions(v any, opts MarshalOptions) (string, error)
MarshalWithOptions converts a Go value to a Filo string with options.
func Unmarshal ¶ added in v0.0.5
Unmarshal converts a Filo string to a Go value. It parses the string, evaluates it, and unmarshals the result into target.
func UnmarshalFromValue ¶ added in v0.0.5
UnmarshalFromValue converts a Filo Value to a Go value. The target must be a non-nil pointer to any Filo-supported type.
Type mapping:
- KBool -> bool
- KNumber -> int, int64, float64, etc.
- KString -> string
- KList -> []T or struct (if list of tuples with string keys)
- KTuple (empty) -> nil pointer
For structs, the list must contain tuples of (string_key, value). Field matching uses the "filo" tag or lowercased field name.
Types ¶
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
func (*Engine) Compile ¶ added in v0.0.5
Compile parses and compiles the source code into a reuseable Program.
func (*Engine) CompileAST ¶ added in v0.0.5
CompileAST compiles a parsed AST into a reusable Program bound to this Engine.
func (*Engine) ExecuteAST ¶ added in v0.0.5
func (e *Engine) ExecuteAST(ctx context.Context, ast Node, globals map[string]Value, cfg EvalConfig) (result Value, newGlobals map[string]Value, err error)
ExecuteAST executes a pre-parsed (and compiled) AST with the given globals. This is the core execution method used by both RunScript and Script.Execute.
func (*Engine) MustRegisterBuiltin ¶
type Filo ¶
type Filo struct {
// contains filtered or unexported fields
}
func (*Filo) CallFunction ¶
CallFunction invokes a Filo-defined function by name with the given arguments. Arguments are converted from Go types to Filo Values. Returns the result Value or an error if the function doesn't exist or fails.
func (*Filo) CallFunctionString ¶
CallFunctionString is a convenience wrapper that calls a function and converts the result to a string. If the function doesn't exist or returns a non-string, the fallback string is returned.
func (*Filo) Close ¶
func (f *Filo) Close()
Close is a no-op for Filo but provided for API compatibility.
func (*Filo) DoString ¶
DoString executes a Filo script and updates globals with any (set ...) statements. This is a convenience method that parses and executes in one call. For scripts executed multiple times, use ParseScript + Execute for better performance.
func (*Filo) Execute ¶ added in v0.0.5
Execute executes a pre-parsed script with optional override globals. Override globals take precedence over instance globals for this execution only. After execution, instance globals are updated with any (set ...) statements.
func (*Filo) GetMapOfLists ¶
func (*Filo) HasFunction ¶
HasFunction checks if a function with the given name is defined in globals.
func (*Filo) MustGetBool ¶
MustGetBool retrieves a global variable as a bool or fatals.
func (*Filo) MustGetInt ¶
MustGetInt retrieves a global variable as an int or fatals.
func (*Filo) MustGetMap ¶
MustGetMap retrieves a global variable as a map[string]string or fatals.
func (*Filo) MustGetMapOfLists ¶
MustGetMapOfLists retrieves a global variable as a map[string][]string or fatals. Expects the structure: (list (list "key" (list "val1" "val2")) ...)
func (*Filo) MustGetString ¶
MustGetString retrieves a global variable as a string or fatals.
func (*Filo) MustGetTable ¶
MustGetTable retrieves a global variable as a []string or fatals.
func (*Filo) RegisterBuiltin ¶
RegisterBuiltin registers a custom builtin function in the Filo engine.
func (*Filo) SetGlobal ¶
SetGlobal sets a global variable that will be available in the Filo script.
func (*Filo) SetGlobalMapOfLists ¶
SetGlobalMapOfLists sets a global variable from a map[string][]string. The structure is stored as a list of (key, list-of-values) tuples. Example: {"a": ["x", "y"]} becomes (list (list "a" (list "x" "y")))
type FormatConfig ¶ added in v0.0.5
type FormatConfig struct {
// Indent is the string used for each indentation level (default: 2 spaces).
Indent string
// MaxLineWidth is the preferred maximum line width (default: 80).
MaxLineWidth int
}
FormatConfig controls formatting behavior.
func DefaultFormatConfig ¶ added in v0.0.5
func DefaultFormatConfig() FormatConfig
DefaultFormatConfig returns the default formatting configuration.
type Frame ¶ added in v0.0.5
type Frame struct {
// contains filtered or unexported fields
}
Frame represents a static lexical scope (activation record). It replaces the map-based Env for local variables.
type GlobalEnv ¶ added in v0.0.5
type GlobalEnv struct {
// contains filtered or unexported fields
}
GlobalEnv represents the global environment (map-based). Unresolved symbols (globals) are looked up here. GlobalEnv represents the global environment using a SymbolTable and array storage.
func NewGlobalEnv ¶ added in v0.0.5
func NewGlobalEnv(symbols *SymbolTable) *GlobalEnv
NewGlobalEnv creates a new global environment linked to a symbol table. It allocates backing storage based on symbol table size.
func (*GlobalEnv) Reset ¶ added in v0.0.5
func (g *GlobalEnv) Reset(symbols *SymbolTable)
Reset clears the global environment for reuse. It keeps the backing array but resets values and defined status.
type MarshalOptions ¶ added in v0.0.5
type MarshalOptions struct {
// Prefix is prepended to each line.
Prefix string
// Indent is added per nesting level.
Indent string
}
Marshal converts a Go value to a Filo Value.
Supported types:
- bool -> KBool
- int, int8, int16, int32, int64 -> KNumber
- uint, uint8, uint16, uint32, uint64 -> KNumber
- float32, float64 -> KNumber
- string -> KString
- []T -> KList (elements converted recursively)
- struct -> KList of (field_name, value) tuples
- map[K]V -> KList of (key, value) tuples (sorted by key for determinism)
- *T -> same as T (nil becomes empty tuple)
Functions and channels are not supported and return an error. MarshalIndent converts a Go value to an indented Filo string. The prefix is prepended to each line (including the first), and indent is added per nesting level.
This is similar to json.MarshalIndent but produces Filo syntax. MarshalOptions configures the marshaling process.
type Node ¶
type Node any
func Compile ¶ added in v0.0.5
func Compile(node Node, builtins map[string]builtinFunc, symbols *SymbolTable) (Node, error)
Compile performs static analysis on the AST to resolve symbols. It returns a new AST with Symbol nodes replaced by ResolvedSymbol where possible, and ResolvedBuiltin for known builtins. Global symbols are resolved to ResolvedGlobal if a SymbolTable is provided.
func FoldConstants ¶ added in v0.0.5
FoldConstants recursively folds constant expressions in the AST. It returns the folded node and true if any change was made, or false otherwise.
Rules: 1. Recursively fold children. 2. If node is a pure function call with all-literal arguments, evaluate it. 3. If node is (if cond then else) and cond is literal bool:
- If true, replace with folded 'then'.
- If false, replace with folded 'else' (or empty if missing).
type ParseError ¶
ParseError represents a syntax/lexing error with a byte position in the source. Position is 0-based and refers to a byte offset in the original string. Near contains a small snippet around the error location to aid debugging.
func (*ParseError) Error ¶
func (e *ParseError) Error() string
type Program ¶ added in v0.0.5
type Program struct {
// contains filtered or unexported fields
}
Program represents a compiled Filo script bound to an Engine instance.
type ResolvedBuiltin ¶ added in v0.0.5
type ResolvedBuiltin struct {
Name string
// contains filtered or unexported fields
}
type ResolvedGlobal ¶ added in v0.0.5
type ResolvedSymbol ¶ added in v0.0.5
type ResolvedSymbol struct {
Name string
Depth int // How many frames up to look (0 = local)
Index int // Index in the frame's slot array
}
ResolvedSymbol represents a symbol resolved to a static frame location.
type Scope ¶ added in v0.0.5
type Scope struct {
// contains filtered or unexported fields
}
Scope represents a lexical scope during compilation.
type Script ¶ added in v0.0.5
type Script struct {
// contains filtered or unexported fields
}
Script represents a pre-parsed Filo script that can be executed multiple times with different globals. This is similar to Go's html/template pattern.
func Must ¶ added in v0.0.5
Must is a helper that wraps a call to ParseScript and panics if the error is non-nil. It is intended for use in variable initializations.
func ParseScript ¶ added in v0.0.5
ParseScript is a convenience function that creates a new Script and parses it.
func (*Script) Execute ¶ added in v0.0.5
func (s *Script) Execute(ctx context.Context, eng *Engine, globals map[string]Value, cfg EvalConfig) (result Value, newGlobals map[string]Value, err error)
Execute runs the pre-parsed script with the given engine, globals, and config.
type SymbolTable ¶ added in v0.0.5
type SymbolTable struct {
// contains filtered or unexported fields
}
SymbolTable manages the mapping between global variable names and their integer IDs. It is thread-safe to allow concurrent compilation/execution sharing the same engine state.
func NewSymbolTable ¶ added in v0.0.5
func NewSymbolTable() *SymbolTable
NewSymbolTable creates a new empty SymbolTable.
func (*SymbolTable) GetID ¶ added in v0.0.5
func (st *SymbolTable) GetID(name string) (int, bool)
GetID returns the ID for a name if it exists, and false otherwise.
func (*SymbolTable) GetName ¶ added in v0.0.5
func (st *SymbolTable) GetName(id int) (string, bool)
GetName returns the name for a given ID if it exists.
func (*SymbolTable) Resolve ¶ added in v0.0.5
func (st *SymbolTable) Resolve(name string) int
Resolve returns the ID for a given symbol name. If the symbol does not exist, it defines it and assigns a new ID.
func (*SymbolTable) Size ¶ added in v0.0.5
func (st *SymbolTable) Size() int
Size returns the number of symbols currently registered.
func (*SymbolTable) Snapshot ¶ added in v0.0.5
func (st *SymbolTable) Snapshot() map[string]int
Snapshot returns a copy of the current symbol map.
type Value ¶
func MarshalToValue ¶ added in v0.0.5
MarshalToValue converts a Go value to a Filo Value.
Supported types:
- bool -> KBool
- int, int8, int16, int32, int64 -> KNumber
- uint, uint8, uint16, uint32, uint64 -> KNumber
- float32, float64 -> KNumber
- string -> KString
- []T -> KList (elements converted recursively)
- struct -> KList of (field_name, value) tuples
- map[K]V -> KList of (key, value) tuples (sorted by key for determinism)
- *T -> same as T (nil becomes empty tuple)
Functions and channels are not supported and return an error.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
filo-repl
command
Command filo-repl provides an interactive REPL for the Filo language.
|
Command filo-repl provides an interactive REPL for the Filo language. |
|
filofmt
command
Command filofmt formats Filo source code files.
|
Command filofmt formats Filo source code files. |
|
examples
|
|
|
autolevel
command
|
|
|
config
command
|
|
|
controlflow
command
|
|
|
custombuiltin
command
|
|
|
filter
command
|
|
|
globals
command
|
|
|
hello
command
|
|
|
json
command
|
|
|
listops
command
|
|
|
marshal
command
Example marshal demonstrates converting Go structs to Filo values and back.
|
Example marshal demonstrates converting Go structs to Filo values and back. |
|
math
command
|
|
|
printf
command
|
|
|
random
command
|
|
|
scoring
command
|
|
|
script
command
Example: Pre-Parse/Execute pattern for efficient script reuse
|
Example: Pre-Parse/Execute pattern for efficient script reuse |
|
sequence
command
|
|
|
strings
command
|
|
|
transform
command
|
|
|
types
command
|
|
|
validation
command
|
|
|
Package filojson provides JSON marshal/unmarshal builtins for the Filo language.
|
Package filojson provides JSON marshal/unmarshal builtins for the Filo language. |
|
Package filomath provides advanced math builtins for the Filo scripting language.
|
Package filomath provides advanced math builtins for the Filo scripting language. |
|
Package filoprint provides simple print builtins for Filo scripts.
|
Package filoprint provides simple print builtins for Filo scripts. |
|
Package filorand provides non-deterministic builtins for Filo.
|
Package filorand provides non-deterministic builtins for Filo. |