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) p.stack[p.sp-p.ctx.count] = unsafe.Pointer(&val)
} }
func (p *process_t) push_context(node *Cnode_t) { 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} 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) { func (p *process_t) pop_context() (*Cnode_t, *Cnode_t) {
var i int var (
i int
node *Cnode_t
container *Cnode_t
)
node = p.ctx.parent_node node = p.ctx.parent_node
container = p.ctx.container_node
// clean up the unused part of the stack // clean up the unused part of the stack
for i = 1; i < p.ctx.count; i++ { 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 { if p.ctx != nil {
p.ctx.count++ // let the return value be the argument to the caller p.ctx.count++ // let the return value be the argument to the caller
} }
return
return node, container
} }
/* func (interp *Interp) eval_node_child(container_node *Cnode_t) (*string, error) {
stmt
text text bracket
stmt: text text
stmt: text TEXT
*/
func (interp *Interp) eval_atom_node(node *Cnode_t) (*string, error) {
var ( var (
p process_t p process_t
v *string v *string
inode *Cnode_t stmt_node *Cnode_t
err error inner_node *Cnode_t
err error
) )
p.interp = interp v = new(string) // TODO: change new(string) to a const
for node != nil { p.interp = interp
p.push_context(node) 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 p.push_string_value("") // placeholder for return value
for inode = node.child; inode != nil; inode = inode.next { start_over:
switch inode.code { inner_node = stmt_node.child
resume:
for inner_node != nil {
switch inner_node.code {
case CNODE_BRACKET: case CNODE_BRACKET:
//p.push_context(inode)
//p.push_string_value("") if inner_node.child != nil {
//node = 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: case CNODE_TEXT:
//fmt.Printf("XXXXXXXXXXXXXXXXXXXx[%s]\n", string(inode.token)) //fmt.Printf("XXXXXXXXXXXXXXXXXXXx[%s]\n", string(child_node.token))
err = p.push_string_value(string(inode.token)) err = p.push_string_value(string(inner_node.token))
if err != nil { if err != nil {
goto oops goto oops
} }
// TODO: many more types...
} }
inner_node = inner_node.next
} }
fmt.Printf("CALLING\n") //fmt.Printf("CALLING\n")
err = p.call() err = p.call()
if err != nil { if err != nil {
goto oops 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()) // get the return value of the statement.
} stmt_node = stmt_node.next
v = (*string)(p.pop_value())
p.pop_context()
if p.ctx != nil {
err = fmt.Errorf("internal error - dangling process context")
goto oops
} }
fmt.Printf("END p.sp = %d\n", p.sp)
return v, nil return v, nil
oops: oops:
return nil, err return nil, err
} }
/*
func (interp *Interp) eval_atom_node_old(node *Cnode_t) (*string, error) { func (interp *Interp) eval_atom_node_old(node *Cnode_t) (*string, error) {
var ( var (
@ -295,6 +316,7 @@ func (interp *Interp) eval_atom_node_old(node *Cnode_t) (*string, error) {
oops: oops:
return nil, err return nil, err
} }
*/
func (interp *Interp) eval_arg(p *process_t, pos int) (*string, error) { func (interp *Interp) eval_arg(p *process_t, pos int) (*string, error) {
var ( var (
@ -305,7 +327,8 @@ func (interp *Interp) eval_arg(p *process_t, pos int) (*string, error) {
if ptr&1 == 1 { // cnode if ptr&1 == 1 { // cnode
ptr &= ^uintptr(1) ptr &= ^uintptr(1)
interp.dump_cnodes((*Cnode_t)(unsafe.Pointer(ptr)), true) 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 { } else {
return (*string)(unsafe.Pointer(ptr)), nil return (*string)(unsafe.Pointer(ptr)), nil
} }

View File

@ -34,9 +34,10 @@ const NULL_RUNE rune = '\u0000'
const EOF_RUNE rune = rune(^0) const EOF_RUNE rune = rune(^0)
type context_t struct { type context_t struct {
count int count int
parent_ctx *context_t parent_ctx *context_t
parent_node *Cnode_t parent_node *Cnode_t
container_node *Cnode_t
} }
type process_t struct { type process_t struct {
@ -245,7 +246,8 @@ func (interp *Interp) Execute(node_head *Cnode_t) (*string, error) {
break 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 { if err != nil {
return nil, err return nil, err
} }