Commit inicial
This commit is contained in:
commit
e3bd2658cd
5 changed files with 512 additions and 0 deletions
117
main.go
Normal file
117
main.go
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
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)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue