diff --git a/ast/eval.go b/ast/eval.go index 01fab12..c7ae665 100644 --- a/ast/eval.go +++ b/ast/eval.go @@ -19,15 +19,17 @@ package ast import "git.callpipe.com/aidan/shs/log" -func (t *Token) Eval(funcs FuncTable, vars VarTable) *Token { +func (t *Token) Eval(funcs FuncTable, vars VarTable) (*Token, bool) { if t == nil { - return nil + return nil, false } eligibleForSystemCall := true var reduce func(*Token) *Token reduce = func(t_ *Token) *Token { + var unwrap bool + if t_.Next != nil { t_.Next = reduce(t_.Next) } @@ -36,7 +38,12 @@ func (t *Token) Eval(funcs FuncTable, vars VarTable) *Token { case SYMBOL: maybeToken := GetVar(t_.Inner.(string), vars) if maybeToken != nil { - tok := maybeToken.Eval(funcs, vars) + tok, _ := maybeToken.Eval(funcs, vars) + // Should already be unwrapped + //if unwrap { + // tok = tok.Inner.(*Token) + //} + if tok.Tag == LIST { eligibleForSystemCall = false } @@ -47,13 +54,33 @@ func (t *Token) Eval(funcs FuncTable, vars VarTable) *Token { case LIST: eligibleForSystemCall = false - t_.Inner = t_.Inner.(*Token).Eval(funcs, vars) + t_.Inner, unwrap = t_.Inner.(*Token).Eval(funcs, vars) + if unwrap { + next := t_.Next + t_ = t_.Inner.(*Token) + if t_ == nil { + log.Log(log.DEBUG, "nil Inner on list unwrap", "eval") + return nil + } + + i := &t_ + for (*i).Next != nil { + i = &((*i).Next) + } + + (*i).Next = next + } } return t_ } ret := reduce(t) + if ret == nil { + log.Log(log.INFO, "reduce returned nil", "eval") + return nil, false + } + if ret.Tag == SYMBOL { f := GetFunction(ret.Inner.(string), funcs) if f == nil { @@ -61,15 +88,15 @@ func (t *Token) Eval(funcs FuncTable, vars VarTable) *Token { log.Log(log.DEBUG, "could not find definition for symbol " + ret.Inner.(string), "eval") - return nil + return nil, false } // TODO: hook into stdlib exec - return nil // TODO: Thats gotta change + return nil, false // TODO: Thats gotta change } - return (*f).CallFunction(ret.Next, vars, funcs) + return (*f).CallFunction(ret.Next, vars, funcs), true } - return ret + return ret, false } diff --git a/cmd/repl.go b/cmd/repl.go index 7678965..22d8a68 100644 --- a/cmd/repl.go +++ b/cmd/repl.go @@ -106,7 +106,13 @@ func main() { ast.PrintSExprsIndividually(userInput) } - result := userInput.Eval(funcs, vars) - fmt.Println(result.String() + "\n") + result, unwrap := userInput.Eval(funcs, vars) + if unwrap { + result = result.Inner.(*ast.Token) + } + for i := result; i != nil; i = i.Next { + fmt.Printf(i.String() + " ") + } + fmt.Printf("\n") } } diff --git a/stdlib/list.go b/stdlib/list.go index 51d6a33..fc5b660 100644 --- a/stdlib/list.go +++ b/stdlib/list.go @@ -61,6 +61,7 @@ func l_append(input *ast.Token, vars ast.VarTable, funcs ast.FuncTable) *ast.Tok iter = &((*iter).Next) } (*iter).Next = input.Next + input.Next = nil - return src.Inner.(*ast.Token) + return src }