updating evaluator code

This commit is contained in:
hyung-hwan 2023-08-03 22:34:42 +09:00
parent 7d01a94d56
commit 379a6e5030
2 changed files with 68 additions and 43 deletions

View File

@ -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
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...
}
fmt.Printf("CALLING\n")
inner_node = inner_node.next
}
//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
}

View File

@ -37,6 +37,7 @@ type context_t struct {
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
}