diff --git a/interp/eval.go b/interp/eval.go index 14d6c3b..f137eff 100644 --- a/interp/eval.go +++ b/interp/eval.go @@ -80,6 +80,12 @@ func (p *process_t) call() error { proc = proc_if case "puts": proc = proc_puts + case "true": + proc = proc_true + case "false": + proc = proc_false + case "null": + proc = proc_null default: proc = proc_unknown } @@ -106,7 +112,7 @@ 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() (*Cnode_t, *Cnode_t) { +func (p *process_t) pop_context(clear_vstack bool) (*Cnode_t, *Cnode_t) { var ( i int node *Cnode_t @@ -116,13 +122,15 @@ func (p *process_t) pop_context() (*Cnode_t, *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++ { - p.vstack[p.vsp-p.ctx.count+i] = nil - } + if clear_vstack { + // clean up the unused part of the stack + for i = 1; i < p.ctx.count; i++ { + p.vstack[p.vsp-p.ctx.count+i] = nil + } - // pop off the cleaned arguments - p.vsp -= p.ctx.count - 1 // keep the return value in the stack + // pop off the cleaned arguments + p.vsp -= p.ctx.count - 1 // keep the return value in the stack + } p.ctx = p.ctx.parent_ctx if p.ctx != nil { @@ -132,7 +140,21 @@ func (p *process_t) pop_context() (*Cnode_t, *Cnode_t) { return node, container } -func (interp *Interp) eval_node_child(container_node *Cnode_t) (*string, error) { +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]) + if x&1 == 0 { + // string value + fmt.Printf(" %d => [%s]\n", i, *(*string)(p.vstack[i])) + } else { + // cnode value + fmt.Printf(" %d => cnode %p", i, p.vstack[i]) // TODO: strip 1 off + } + } +} +func (interp *Interp) eval_stmt_nodes(container_node *Cnode_t) (*string, error) { var ( p process_t v *string @@ -144,7 +166,7 @@ func (interp *Interp) eval_node_child(container_node *Cnode_t) (*string, error) v = new(string) // TODO: change new(string) to a const p.interp = interp - stmt_node = container_node.child + stmt_node = container_node.child // the first statement //interp.dump_cnodes(container_node, true) //fmt.Printf("--------------\n") @@ -164,19 +186,36 @@ func (interp *Interp) eval_node_child(container_node *Cnode_t) (*string, error) inner_node = stmt_node.child resume: for inner_node != nil { + //fmt.Printf("handling %d\n", inner_node.code) switch inner_node.code { case CNODE_BRACKET: - case CNODE_DQUOTE: if inner_node.child != nil { stmt_node = inner_node.child // first statement inside [] p.push_context(stmt_node, inner_node) - p.push_string_value("") + p.push_string_value("") // for return value + fmt.Printf("going to start over\n") + interp.dump_cnodes(stmt_node, true) + fmt.Printf("\n--\n") goto start_over } else { // no statements inside []. treat it like an empty string p.push_string_value("") } + case CNODE_DQUOTE: + if inner_node.child != nil { + p.push_context(stmt_node, inner_node) + //p.push_string_value("") // no placeholder for return value is needed + inner_node = inner_node.child + fmt.Printf("going to start over\n") + interp.dump_cnodes(stmt_node, true) + fmt.Printf("\n--\n") + goto resume + } else { + // no statements inside []. treat it like an empty string + p.push_string_value("") + } + case CNODE_BRACE: p.push_cnode_value(inner_node) @@ -189,23 +228,33 @@ func (interp *Interp) eval_node_child(container_node *Cnode_t) (*string, error) } // TODO: many more types... + case CNODE_JOIN: + //fmt.Printf("JOIN>>>>>\n") + p.merge_top_values() } inner_node = inner_node.next } - fmt.Printf("CALLING for %d\n", p.ctx.parent_node.code) - if p.ctx.parent_node.code == CNODE_STMT { + 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("calling..... [%s]\n", *p.GetCalleeName()) err = p.call() if err != nil { goto oops } + + stmt_node, inner_node = p.pop_context(true) } else { - fmt.Printf("DDDDDDDDDDDDBVVVVVVVVVVVDDDd\n") + + // join the all + stmt_node, inner_node = p.pop_context(false) } - stmt_node, inner_node = p.pop_context() if inner_node != nil { + fmt.Printf("resuming... %d\n", p.vsp) inner_node = inner_node.next goto resume } @@ -214,6 +263,7 @@ func (interp *Interp) eval_node_child(container_node *Cnode_t) (*string, error) stmt_node = stmt_node.next } + interp.dump_vstack(&p) fmt.Printf("END p.sp = %d\n", p.vsp) return v, nil @@ -342,7 +392,7 @@ func (interp *Interp) eval_arg(p *process_t, pos int) (*string, error) { 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_node_child((*Cnode_t)(unsafe.Pointer(ptr))) + return interp.eval_stmt_nodes((*Cnode_t)(unsafe.Pointer(ptr))) } else { return (*string)(unsafe.Pointer(ptr)), nil } diff --git a/interp/pcl.go b/interp/pcl.go index 900dfe6..bdfa6ef 100644 --- a/interp/pcl.go +++ b/interp/pcl.go @@ -247,7 +247,7 @@ func (interp *Interp) Execute(node_head *Cnode_t) (*string, error) { } //v, err = interp.eval_node_child(node.child) - v, err = interp.eval_node_child(node) + v, err = interp.eval_stmt_nodes(node) if err != nil { return nil, err } diff --git a/interp/proc.go b/interp/proc.go index 333a6d9..c216141 100644 --- a/interp/proc.go +++ b/interp/proc.go @@ -70,6 +70,20 @@ func proc_puts(p *process_t) error { return nil } +func proc_false(p *process_t) error { + p.Return("false") + return nil +} +func proc_true(p *process_t) error { + p.Return("true") + return nil +} + +func proc_null(p *process_t) error { + p.Return("") + return nil +} + func proc_unknown(p *process_t) error { fmt.Printf("Unknown command - %s\n", *(p.GetCalleeName())) return nil