eval: add write, eval arguments before applying function

This commit is contained in:
2018-05-15 22:13:43 +02:00
parent 45822a2ecd
commit 6413bd7e81
4 changed files with 53 additions and 16 deletions

View File

@@ -120,6 +120,16 @@ func (ast *AST) Pretty() string {
return fmt.Sprintf("%v", ast.Val)
}
func (ast *AST) String() string {
switch ast.Tag {
case List, Quoted, Fn, Table, Prim:
return ast.Pretty()
case Char:
return string(ast.Val.(rune))
}
return fmt.Sprintf("%v", ast.Val)
}
type Env struct {
parent *Env
Values map[string]*AST

View File

@@ -24,6 +24,7 @@ func RootEnv() ast.Env {
"cdr": evalCdr,
"null?": evalNull,
"pr": evalPr,
"write": evalWrite,
"table": evalTable,
"type": evalType,
"len": evalLen,
@@ -318,11 +319,23 @@ func funcApply(f ast.Func, args []*ast.AST, e ast.Env) (*ast.AST, error) {
}
for i, a := range f.Params {
f.Env.Values[a] = args[i]
evald, err := Eval(args[i], e)
if err != nil {
return nil, err
}
f.Env.Values[a] = evald
}
if f.HasRest() {
lst := ast.AST{ast.List, args[plen:]}
var l []*ast.AST
for _, arg := range args[plen:] {
evald, err := Eval(arg, e)
if err != nil {
return nil, err
}
l = append(l, evald)
}
lst := ast.AST{ast.List, l}
quoted := ast.AST{ast.Quoted, &lst}
f.Env.Values[*f.Rest] = &quoted
} else {
@@ -330,7 +343,11 @@ func funcApply(f ast.Func, args []*ast.AST, e ast.Env) (*ast.AST, error) {
i := plen
for kv, ok := iter(); ok; kv, ok = iter() {
if i < alen {
f.Env.Values[kv.Key.(string)] = args[i]
evald, err := Eval(args[i], e)
if err != nil {
return nil, err
}
f.Env.Values[kv.Key.(string)] = evald
} else {
f.Env.Values[kv.Key.(string)] = kv.Value.(*ast.AST)
}
@@ -350,6 +367,15 @@ func evalPr(l []*ast.AST) (*ast.AST, error) {
return &nilVal, nil
}
func evalWrite(l []*ast.AST) (*ast.AST, error) {
var toPrint []string
for _, elem := range l {
toPrint = append(toPrint, elem.String())
}
fmt.Print(strings.Join(toPrint, " "))
return &nilVal, nil
}
func evalIf(l []*ast.AST, e ast.Env) (*ast.AST, error) {
i := 0
for i < len(l) {

View File

@@ -94,14 +94,12 @@ func runFile(path string) {
return
}
evald, err := eval.Eval(expanded, e)
_, err = eval.Eval(expanded, e)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(evald.Pretty())
}
}

View File

@@ -76,17 +76,20 @@ func parseValue(input []string) (*ast.AST, error, []string) {
}
if input[0][0] == '"' {
agg := []string{input[0]}
start := input[0]
agg := []string{start}
input = input[1:]
for {
if len(input) == 0 {
return nil, errors.New("Unmatched \""), input
}
token := input[0]
input = input[1:]
agg = append(agg, token)
if token[len(token)-1] == '"' {
break
if start[len(start)-1] != '"' {
for {
if len(input) == 0 {
return nil, errors.New("Unmatched \""), input
}
token := input[0]
input = input[1:]
agg = append(agg, token)
if token[len(token)-1] == '"' {
break
}
}
}
joined := strings.Join(agg, " ")