all: add optional args

This commit is contained in:
2018-05-14 21:48:44 +02:00
parent fae99aedd8
commit ac880c26a6
4 changed files with 139 additions and 101 deletions

View File

@@ -3,6 +3,8 @@ package ast
import (
"fmt"
"strings"
"github.com/cevaris/ordered_map"
)
type AST struct {
@@ -21,8 +23,8 @@ const (
Fn
Char
Table
Prim
Quoted
Prim
Quoted
)
func (tag Tag) String() string {
@@ -56,20 +58,20 @@ func (ast *AST) Type() *AST {
"cons",
}
if ast.Tag == Quoted {
return ast.Val.(*AST).Type()
}
if ast.Tag == Quoted {
return ast.Val.(*AST).Type()
}
name := names[ast.Tag]
if ast.Tag == Num {
val := ast.Val.(float64)
if val == float64(int64(val)) {
name = "int"
}
}
name := names[ast.Tag]
if ast.Tag == Num {
val := ast.Val.(float64)
if val == float64(int64(val)) {
name = "int"
}
}
res := AST{Symbol, name}
return &res
res := AST{Symbol, name}
return &res
}
func (ast *AST) Pretty() string {
@@ -87,11 +89,12 @@ func (ast *AST) Pretty() string {
for _, elem := range val.Params {
agg = append(agg, elem)
}
opt := ""
if val.HasOpt() {
opt = " . " + *val.Opt
}
body := val.Body.Pretty()
opt := ""
if val.HasRest() {
opt = " . " + *val.Rest
}
// TODO: opt
body := val.Body.Pretty()
return "(fn (" + strings.Join(agg, " ") + opt + ") " + body + ")"
} else if ast.Tag == Char {
return "#" + string(ast.Val.(rune))
@@ -104,8 +107,8 @@ func (ast *AST) Pretty() string {
return "#hash(" + strings.Join(agg, " ") + ")"
} else if ast.Tag == Prim {
return "#<procedure: " + ast.Val.(Primitive).Name + ">"
}
return "#<procedure: " + ast.Val.(Primitive).Name + ">"
}
return fmt.Sprintf("%v", ast.Val)
}
@@ -117,16 +120,16 @@ type Env struct {
type PrimFn func([]*AST) (*AST, error)
type Primitive struct {
Name string
Fn PrimFn
Name string
Fn PrimFn
}
func newEnv(parent *Env) Env {
func NewEnv(parent *Env) Env {
return Env{parent, make(map[string]*AST)}
}
func ParentEnv() Env {
return newEnv(nil)
return NewEnv(nil)
}
func (e *Env) Lookup(elem string) (*AST, error) {
@@ -145,11 +148,16 @@ func (e *Env) Lookup(elem string) (*AST, error) {
type Func struct {
Params []string
Opt *string
Rest *string
Opt *ordered_map.OrderedMap
Body *AST
Env Env
}
func (f *Func) HasOpt() bool {
return f.Opt != nil
func (f *Func) HasRest() bool {
return f.Rest != nil
}
func (f *Func) HasOpt() bool {
return f.Opt.Len() != 0
}