Lambda
This commit is contained in:
parent
e3bd2658cd
commit
7c40723537
3 changed files with 143 additions and 21 deletions
81
main.go
81
main.go
|
|
@ -13,14 +13,35 @@ 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 "+":
|
||||
|
|
@ -37,7 +58,6 @@ func (v *Identifier) Step() (Expression, error) {
|
|||
sum += x.value.value
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid type")
|
||||
|
||||
}
|
||||
}
|
||||
return &Value[int]{sum}, nil
|
||||
|
|
@ -48,6 +68,50 @@ func (v *Identifier) Step() (Expression, error) {
|
|||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
|
|
@ -73,6 +137,19 @@ func (v *List) Step() (Expression, error) {
|
|||
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:
|
||||
|
|
@ -86,7 +163,7 @@ func fullStep(e Expression) (Expression, error) {
|
|||
for !isValue(e) {
|
||||
n, err := e.Step()
|
||||
if err != nil {
|
||||
return n, nil
|
||||
return nil, err
|
||||
}
|
||||
e = n
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue