package main import ( "fmt" "os" ) var source = ` (+ 1 2 3 4) ` func (v *Value[T]) Step() (Expression, error) { return v, nil } func (v *Quoted) Step() (Expression, error) { return v, nil } func (d *Declaration) Step() (Expression, error) { return &Value[int]{0}, nil } func (v *Identifier) Step() (Expression, error) { switch v.value { case "+": f := func(args []Expression) (Expression, error) { sum := 0 for _, arg := range args { if !isValue(arg) { panic("!") } switch x := arg.(type) { case *Value[int]: sum += x.value case *Value[*Int]: sum += x.value.value default: return nil, fmt.Errorf("invalid type") } } return &Value[int]{sum}, nil } return &Value[Function]{f}, nil default: panic("!") } } func (v *List) Step() (Expression, error) { for i, expr := range v.els { if !isValue(expr) { e, err := expr.Step() if err != nil { return nil, err } v.els[i] = e return v, nil } } if len(v.els) == 0 { return nil, fmt.Errorf("empty list") } f, ok := v.els[0].(*Value[Function]) if !ok { return nil, fmt.Errorf("not a function") } r, err := f.value(v.els[1:]) if err != nil { return nil, err } return r, nil } func isValue(e Expression) bool { switch e.(type) { case *Value[int], *Value[*Int], *Value[Function], *Quoted: return true default: return false } } func fullStep(e Expression) (Expression, error) { for !isValue(e) { n, err := e.Step() if err != nil { return n, nil } e = n } return e, nil } func main() { if len(os.Args) > 1 { source = os.Args[1] } tk, err := lex(source) if err != nil { panic(err) } p, err := consume(tk) if err != nil { panic(err) } s, err := p.Step() if err != nil { panic(err) } result, err := fullStep(s) if err != nil { panic(err) } fmt.Println(result) }