Updates args-list based variadic procs to allow zero args to be given for args-list, which will now yield and empty list

master
sloum 2 years ago
parent bdd3430a5a
commit e1c49b4fb2

@ -0,0 +1,13 @@
package main
import (
"fmt"
"strings"
)
func Fmt(s string) {
var out strings.Builder
// exps := Parse(s)
fmt.Println(out.String())
}

@ -556,3 +556,19 @@ func stringParensMatch(s string) bool {
// parser will handle erroring
return true
}
//
func variadic(l expression) int {
list, ok := l.([]expression)
if !ok || len(list) == 0 {
return 0
}
v, ok := list[len(list)-1].(symbol)
if !ok {
return 0
}
if v == symbol("args-list") {
return 1
}
return 0
}

@ -90,7 +90,7 @@ func eval(exp expression, en *env) (value expression) {
value = exception("Invalid 'cond' syntax - too few arguments")
break
}
CondLoop:
CondLoop:
for _, exp := range e[1:] {
switch i := exp.(type) {
case []expression:
@ -167,7 +167,7 @@ func eval(exp expression, en *env) (value expression) {
sort.Strings(keys)
for i := range keys {
out.WriteString(fmt.Sprintf("%-26s", keys[i]))
if (i+1) % 2 == 0 {
if (i+1)%2 == 0 {
out.WriteRune('\n')
}
}
@ -299,12 +299,16 @@ func apply(procedure expression, args []expression) (value expression) {
en := &env{make(vars), p.en}
switch params := p.params.(type) {
case []expression:
if len(params) > len(args) {
if len(params)-variadic(params) > len(args) {
return expression(fmt.Sprintf("Lambda expected %d arguments but received %d", len(params), len(args)))
}
for i, param := range params {
if param.(symbol) == symbol("args-list") {
en.vars[param.(symbol)] = args[i:]
if len(args) >= len(params) {
en.vars[param.(symbol)] = args[i:]
} else {
en.vars[param.(symbol)] = make([]expression, 0)
}
break
}
en.vars[param.(symbol)] = args[i]

Loading…
Cancel
Save