diff --git a/interp/eval.go b/interp/eval.go index 995469e..ad14c3b 100644 --- a/interp/eval.go +++ b/interp/eval.go @@ -5,7 +5,7 @@ import ( "unsafe" ) -var debug bool = false +var debug bool = true var err_num_args *error_t = &error_t{msg: "wrong number of arguments"} @@ -143,7 +143,6 @@ func (p *process_t) pop_context(clear_vstack bool) (*Cnode_t, *Cnode_t) { } func (interp *Interp) dump_vstack(p *process_t) { - //fmt.Printf("DDDDDDDDDDDDBVVVVVVVVVVVDDDd\n") fmt.Printf("p.VSP => %d\n", p.vsp) for i := 0; i < p.vsp; i++ { x := uintptr(p.vstack[i]) @@ -158,15 +157,20 @@ func (interp *Interp) dump_vstack(p *process_t) { } /* - [STMT] - [TEXT] [DQUOTE] [TEXT] +puts "hello" world [STMT] - [BRACKET] [TEXT] + [TEXT|puts] [DQUOTE] [TEXT|world] + [TEXT|hello] + +[puts 1 2; puts 1] 999 + + [STMT] + [BRACKET] [TEXT|999] [STMT] - [TEXT] [TEXT] [TEXT] + [TEXT|puts] [TEXT|1] [TEXT|2] [STMT] - [TEXT] [TEXT] + [TEXT|puts] [TEXT|1] "pu[null 1]ts" 10 20 @@ -181,30 +185,31 @@ func (interp *Interp) eval_stmt_nodes(container_node *Cnode_t) (*string, error) p process_t v *string stmt_node *Cnode_t + upper_node *Cnode_t inner_node *Cnode_t + is_stmt bool err error ) v = new(string) // TODO: change new(string) to a const p.interp = interp - stmt_node = container_node.child // the first statement - - //interp.dump_cnodes(container_node, true) - //fmt.Printf("--------------\n") - //interp.dump_cnodes(stmt_node, true) - //fmt.Printf("--------------\n") + upper_node = container_node + stmt_node = upper_node.child // the first statement fmt.Printf("START p.sp = %d\n", p.vsp) + for stmt_node != nil { + start_over_0: if stmt_node.code != CNODE_STMT { panic("internal error - not statement node") } - p.push_context(stmt_node, nil) + //fmt.Printf("PUSHING CONTEXT.....\n") + p.push_context(stmt_node, upper_node) p.push_string_value("") // placeholder for return value - start_over: + //start_over: inner_node = stmt_node.child resume: for inner_node != nil { @@ -212,15 +217,14 @@ func (interp *Interp) eval_stmt_nodes(container_node *Cnode_t) (*string, error) switch inner_node.code { case CNODE_BRACKET: if inner_node.child != nil { - stmt_node = inner_node.child // first statement inside [] - p.push_context(stmt_node, inner_node) - p.push_string_value("") // for return value + upper_node = inner_node + stmt_node = upper_node.child if debug { fmt.Printf("going to start over\n") interp.dump_cnodes(stmt_node, true) fmt.Printf("\n--\n") } - goto start_over + goto start_over_0 } else { // no statements inside []. treat it like an empty string p.push_string_value("") @@ -228,6 +232,7 @@ func (interp *Interp) eval_stmt_nodes(container_node *Cnode_t) (*string, error) case CNODE_DQUOTE: if inner_node.child != nil { + //fmt.Printf("PUSHING CONTEXT.....\n") p.push_context(stmt_node, inner_node) //p.push_string_value("") // no placeholder for return value is needed inner_node = inner_node.child @@ -255,7 +260,6 @@ func (interp *Interp) eval_stmt_nodes(container_node *Cnode_t) (*string, error) // TODO: many more types... case CNODE_JOIN: - //fmt.Printf("JOIN>>>>>\n") p.merge_top_values() } @@ -265,9 +269,8 @@ func (interp *Interp) eval_stmt_nodes(container_node *Cnode_t) (*string, error) if debug { interp.dump_vstack(&p) } - //fmt.Printf("p.ctx.parent_node.code %d p.ctx.container_node.code %d CNODE_STMT %d CNODE_DQUOTE %d\n", p.ctx.parent_node.code, p.ctx.container_node.code, CNODE_STMT, CNODE_DQUOTE) - //if p.ctx.parent_node.code == CNODE_STMT { - if p.ctx.container_node == nil || (p.ctx.container_node.code == CNODE_STMT || p.ctx.container_node.code == CNODE_BRACKET) { + //fmt.Printf("p.ctx.parent_node.code %d p.ctx.container_node.code %d CNODE_STMT %d CNODE_DQUOTE %d CNODE_BRACKET %d\n", p.ctx.parent_node.code, p.ctx.container_node.code, CNODE_STMT, CNODE_DQUOTE, CNODE_BRACKET) + if p.ctx.container_node.code == CNODE_INIT || p.ctx.container_node.code == CNODE_BRACKET { if debug { fmt.Printf("calling..... [%s]\n", *p.GetCalleeName()) } @@ -276,20 +279,26 @@ func (interp *Interp) eval_stmt_nodes(container_node *Cnode_t) (*string, error) goto oops } - stmt_node, inner_node = p.pop_context(true) + is_stmt = true } else { - stmt_node, inner_node = p.pop_context(false) + is_stmt = false } - if inner_node != nil { + //fmt.Printf("POPPING CONTEXT.....is_stmt[%v]\n", is_stmt) + stmt_node, upper_node = p.pop_context(is_stmt) + if upper_node != container_node { if debug { - fmt.Printf("resuming... %d\n", p.vsp) + fmt.Printf("resuming... %d upper_node.next %p\n", p.vsp, upper_node.next) } - inner_node = inner_node.next + inner_node = upper_node.next // as if it hit the bottom of the innner for loop goto resume } + //fmt.Printf("POPPING VALUE...\n") v = (*string)(p.pop_value()) // get the return value of the statement. + if debug { + interp.dump_vstack(&p) + } stmt_node = stmt_node.next } @@ -303,117 +312,6 @@ oops: return nil, err } -/* -func (interp *Interp) eval_atom_node_old(node *Cnode_t) (*string, error) { - - var ( - p process_t - v *string - err error - ) - - p.interp = interp - p.push_context(nil) - p.push_string_value("") // placeholder for return value - - for node != nil { - switch node.code { - case CNODE_BRACKET: // this is a container - if node.child != nil { - p.push_context(node) - err = p.push_string_value("") // placeholder for return value - if err != nil { - goto oops - } - node = node.child - continue - } else { - err = p.push_string_value("") - if err != nil { - goto oops - } - } - - case CNODE_BRACE: // this is a container - err = p.push_cnode_value(node) - if err != nil { - goto oops - } - - case CNODE_DQUOTE: // this is a container - // TODO: at the feed layer, recompose CNODE_DQUOTE item to - // successive ATOM item - // "abc $ddd [xx 11]" must be TEXT("abc ") + VAR("ddd") + BRACKET["xx 11"] without SEP in between - - // this is not right..... - if node.child != nil { - // TODO: something is not right here. handle inner stuffs - //fmt.Printf("pushing [%s]\n", string(node.child.token)) - err = p.push_string_value(string(node.child.token)) - } else { - err = p.push_string_value("") - } - if err != nil { - goto oops - } - - case CNODE_VAR: - - case CNODE_TEXT: - //fmt.Printf("pushing [%s]\n", string(node.token)) - err = p.push_string_value(string(node.token)) - if err != nil { - goto oops - } - - default: - err = fmt.Errorf("internal error - non-atom node - %d", node.code) - goto oops - } - - node = node.next - check_end: - if node == nil { // reached the last node - err = p.call() - if err != nil { - goto oops - } - if p.ctx.parent_ctx != nil { - node = p.pop_context() - if node.seqno > 0 { - // merge the top 2 values (return from [] + previous argument) - // for instance, the expression `aa[qq 11]` must product a single word - // `aa` concatenated of the result of `qq 11` - err = p.merge_top_values() - if err != nil { - goto oops - } - } - node = node.next - - // take `aa 11 22 [dd [bb cc]]` as an example - // after [bb cc] is called, it must call `[dd]`` followed by `aa`. - // this goto loop is to handle successive calls when a nested call is the - // last argument - goto check_end - } - } - } - - v = (*string)(p.pop_value()) - p.pop_context() - if p.ctx != nil { - err = fmt.Errorf("internal error - dangling process context") - goto oops - } - - return v, nil - -oops: - return nil, err -} -*/ - func (interp *Interp) eval_arg(p *process_t, pos int) (*string, error) { var ( ptr uintptr