eval: add write, eval arguments before applying function
This commit is contained in:
10
ast/ast.go
10
ast/ast.go
@@ -120,6 +120,16 @@ func (ast *AST) Pretty() string {
|
|||||||
return fmt.Sprintf("%v", ast.Val)
|
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 {
|
type Env struct {
|
||||||
parent *Env
|
parent *Env
|
||||||
Values map[string]*AST
|
Values map[string]*AST
|
||||||
|
32
eval/eval.go
32
eval/eval.go
@@ -24,6 +24,7 @@ func RootEnv() ast.Env {
|
|||||||
"cdr": evalCdr,
|
"cdr": evalCdr,
|
||||||
"null?": evalNull,
|
"null?": evalNull,
|
||||||
"pr": evalPr,
|
"pr": evalPr,
|
||||||
|
"write": evalWrite,
|
||||||
"table": evalTable,
|
"table": evalTable,
|
||||||
"type": evalType,
|
"type": evalType,
|
||||||
"len": evalLen,
|
"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 {
|
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() {
|
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}
|
quoted := ast.AST{ast.Quoted, &lst}
|
||||||
f.Env.Values[*f.Rest] = "ed
|
f.Env.Values[*f.Rest] = "ed
|
||||||
} else {
|
} else {
|
||||||
@@ -330,7 +343,11 @@ func funcApply(f ast.Func, args []*ast.AST, e ast.Env) (*ast.AST, error) {
|
|||||||
i := plen
|
i := plen
|
||||||
for kv, ok := iter(); ok; kv, ok = iter() {
|
for kv, ok := iter(); ok; kv, ok = iter() {
|
||||||
if i < alen {
|
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 {
|
} else {
|
||||||
f.Env.Values[kv.Key.(string)] = kv.Value.(*ast.AST)
|
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
|
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) {
|
func evalIf(l []*ast.AST, e ast.Env) (*ast.AST, error) {
|
||||||
i := 0
|
i := 0
|
||||||
for i < len(l) {
|
for i < len(l) {
|
||||||
|
4
main.go
4
main.go
@@ -94,14 +94,12 @@ func runFile(path string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
evald, err := eval.Eval(expanded, e)
|
_, err = eval.Eval(expanded, e)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(evald.Pretty())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -76,8 +76,10 @@ func parseValue(input []string) (*ast.AST, error, []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if input[0][0] == '"' {
|
if input[0][0] == '"' {
|
||||||
agg := []string{input[0]}
|
start := input[0]
|
||||||
|
agg := []string{start}
|
||||||
input = input[1:]
|
input = input[1:]
|
||||||
|
if start[len(start)-1] != '"' {
|
||||||
for {
|
for {
|
||||||
if len(input) == 0 {
|
if len(input) == 0 {
|
||||||
return nil, errors.New("Unmatched \""), input
|
return nil, errors.New("Unmatched \""), input
|
||||||
@@ -89,6 +91,7 @@ func parseValue(input []string) (*ast.AST, error, []string) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
joined := strings.Join(agg, " ")
|
joined := strings.Join(agg, " ")
|
||||||
res = ast.AST{ast.String, joined[1 : len(joined)-1]}
|
res = ast.AST{ast.String, joined[1 : len(joined)-1]}
|
||||||
return &res, nil, input
|
return &res, nil, input
|
||||||
|
Reference in New Issue
Block a user