package main import ( "fmt" "os" ) var source = ` (+ 1 2 3 4) ` func (v *Value[T]) Step() (Expression, error) { return v, nil } func (v *Value[T]) Replace(Id, Expression) { } func (v *Quoted) Step() (Expression, error) { return v, nil } func (v *Quoted) Replace(Id, Expression) { } func (d *Declaration) Step() (Expression, error) { return &Value[int]{0}, nil } func (v *Declaration) Replace(id Id, expr Expression) { if id == v.id.value { return } else { switch x := v.expr.(type) { case *Identifier: if x.value == id { v.expr = expr } default: x.Replace(id, expr) } } } 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 *Identifier) Replace(id Id, expr Expression) { panic("!") } func (l *Lambda) Step() (Expression, error) { f := func(args []Expression) (Expression, error) { if len(args) != len(l.args) { return nil, fmt.Errorf("unexpected number of arguments") } for i, arg := range l.args { argExpr := args[i] for j, e := range l.body { switch x := e.(type) { case *Identifier: if x.value == arg.value { l.body[j] = argExpr } default: e.Replace(arg.value, argExpr) } } } if len(l.body) == 0 { return &Value[int]{0}, nil } for i, expr := range l.body { if isValue(expr) { continue } r, err := expr.Step() if err != nil { return nil, err } l.body[i] = r } return l.body[len(l.body)-1], nil } return &Value[Function]{f}, nil } func (l *Lambda) Replace(id Id, expr Expression) { 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 (v *List) Replace(id Id, expr Expression) { for i, e := range v.els { switch x := e.(type) { case *Identifier: if x.value == id { v.els[i] = expr } default: e.Replace(id, expr) } } } 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 nil, err } 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) }