diff --git a/interp/eval.go b/interp/eval.go index 1d3b10e..b5a69c7 100644 --- a/interp/eval.go +++ b/interp/eval.go @@ -100,14 +100,19 @@ func (p *process_t) Return(val string) { p.stack[p.sp-p.ctx.count] = unsafe.Pointer(&val) } -func (p *process_t) push_context(node *Cnode_t) { - p.ctx = &context_t{count: 0, parent_ctx: p.ctx, parent_node: node} +func (p *process_t) push_context(node *Cnode_t, container_node *Cnode_t) { + p.ctx = &context_t{count: 0, parent_ctx: p.ctx, parent_node: node, container_node: container_node} } -func (p *process_t) pop_context() (node *Cnode_t) { - var i int +func (p *process_t) pop_context() (*Cnode_t, *Cnode_t) { + var ( + i int + node *Cnode_t + container *Cnode_t + ) node = p.ctx.parent_node + container = p.ctx.container_node // clean up the unused part of the stack for i = 1; i < p.ctx.count; i++ { @@ -121,72 +126,88 @@ func (p *process_t) pop_context() (node *Cnode_t) { if p.ctx != nil { p.ctx.count++ // let the return value be the argument to the caller } - return + + return node, container } -/* -stmt - - text text bracket - stmt: text text - stmt: text TEXT -*/ -func (interp *Interp) eval_atom_node(node *Cnode_t) (*string, error) { +func (interp *Interp) eval_node_child(container_node *Cnode_t) (*string, error) { var ( - p process_t - v *string - inode *Cnode_t - err error + p process_t + v *string + stmt_node *Cnode_t + inner_node *Cnode_t + err error ) - p.interp = interp + v = new(string) // TODO: change new(string) to a const - for node != nil { - p.push_context(node) + p.interp = interp + stmt_node = container_node.child + + fmt.Printf("START p.sp = %d\n", p.sp) + for stmt_node != nil { + if stmt_node.code != CNODE_STMT { + panic("internal error - not statement node") + } + + p.push_context(stmt_node, nil) p.push_string_value("") // placeholder for return value - for inode = node.child; inode != nil; inode = inode.next { - switch inode.code { + start_over: + inner_node = stmt_node.child + resume: + for inner_node != nil { + switch inner_node.code { case CNODE_BRACKET: - //p.push_context(inode) - //p.push_string_value("") - //node = + + if inner_node.child != nil { + stmt_node = inner_node.child // first statement inside [] + p.push_context(stmt_node, inner_node) + p.push_string_value("") + goto start_over + } else { + // no statements inside []. treat it like an empty string + p.push_string_value("") + } case CNODE_TEXT: - //fmt.Printf("XXXXXXXXXXXXXXXXXXXx[%s]\n", string(inode.token)) - err = p.push_string_value(string(inode.token)) + //fmt.Printf("XXXXXXXXXXXXXXXXXXXx[%s]\n", string(child_node.token)) + err = p.push_string_value(string(inner_node.token)) if err != nil { goto oops } + + // TODO: many more types... } + + inner_node = inner_node.next } - fmt.Printf("CALLING\n") + //fmt.Printf("CALLING\n") err = p.call() if err != nil { goto oops } - if p.ctx.parent_ctx != nil { - p.pop_context() + + stmt_node, inner_node = p.pop_context() + if inner_node != nil { + inner_node = inner_node.next + goto resume } - node = node.next - } - - v = (*string)(p.pop_value()) - p.pop_context() - if p.ctx != nil { - err = fmt.Errorf("internal error - dangling process context") - goto oops + v = (*string)(p.pop_value()) // get the return value of the statement. + stmt_node = stmt_node.next } + fmt.Printf("END p.sp = %d\n", p.sp) return v, nil oops: return nil, err } +/* func (interp *Interp) eval_atom_node_old(node *Cnode_t) (*string, error) { var ( @@ -295,6 +316,7 @@ func (interp *Interp) eval_atom_node_old(node *Cnode_t) (*string, error) { oops: return nil, err } +*/ func (interp *Interp) eval_arg(p *process_t, pos int) (*string, error) { var ( @@ -305,7 +327,8 @@ func (interp *Interp) eval_arg(p *process_t, pos int) (*string, error) { if ptr&1 == 1 { // cnode ptr &= ^uintptr(1) interp.dump_cnodes((*Cnode_t)(unsafe.Pointer(ptr)), true) - return interp.eval_atom_node((*Cnode_t)(unsafe.Pointer(ptr)).child) + //return interp.eval_atom_node((*Cnode_t)(unsafe.Pointer(ptr)).child) + return interp.eval_node_child((*Cnode_t)(unsafe.Pointer(ptr))) } else { return (*string)(unsafe.Pointer(ptr)), nil } diff --git a/interp/pcl.go b/interp/pcl.go index 2d2d031..714784b 100644 --- a/interp/pcl.go +++ b/interp/pcl.go @@ -34,9 +34,10 @@ const NULL_RUNE rune = '\u0000' const EOF_RUNE rune = rune(^0) type context_t struct { - count int - parent_ctx *context_t - parent_node *Cnode_t + count int + parent_ctx *context_t + parent_node *Cnode_t + container_node *Cnode_t } type process_t struct { @@ -245,7 +246,8 @@ func (interp *Interp) Execute(node_head *Cnode_t) (*string, error) { break } - v, err = interp.eval_atom_node(node.child) + //v, err = interp.eval_node_child(node.child) + v, err = interp.eval_node_child(node) if err != nil { return nil, err }