Commit inicial

This commit is contained in:
silva guimaraes 2025-05-25 02:35:11 -03:00
commit e3bd2658cd
5 changed files with 512 additions and 0 deletions

117
main.go Normal file
View 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)
}