implementing the evaluator

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

View File

@ -8,9 +8,9 @@ import (
var err_num_args *error_t = &error_t{msg: "wrong number of arguments"} var err_num_args *error_t = &error_t{msg: "wrong number of arguments"}
/* /*
value stack (p.stack) value stack (p.vstack)
<--- SP <--- SP (p.vsp)
ARG1 ARG1
ARG0 ARG0
NAME NAME
@ -20,24 +20,26 @@ var err_num_args *error_t = &error_t{msg: "wrong number of arguments"}
*/ */
func (p *process_t) push_cnode_value(val *Cnode_t) error { func (p *process_t) push_cnode_value(val *Cnode_t) error {
if p.sp >= cap(p.stack) { if p.vsp >= cap(p.vstack) {
return fmt.Errorf("stack full") return fmt.Errorf("stack full")
} }
p.stack[p.sp] = unsafe.Pointer(uintptr(unsafe.Pointer(val)) | 1) // TODO: using the last bit won't be compatible with go's GC.
p.sp++ // CHANGE to use inteface{} or devise a different scheme...
p.vstack[p.vsp] = unsafe.Pointer(uintptr(unsafe.Pointer(val)) | 1)
p.vsp++
p.ctx.count++ p.ctx.count++
return nil return nil
} }
func (p *process_t) push_string_value(val string) error { func (p *process_t) push_string_value(val string) error {
if p.sp >= cap(p.stack) { if p.vsp >= cap(p.vstack) {
return fmt.Errorf("stack full") return fmt.Errorf("stack full")
} }
p.stack[p.sp] = unsafe.Pointer(&val) p.vstack[p.vsp] = unsafe.Pointer(&val)
p.sp++ p.vsp++
p.ctx.count++ p.ctx.count++
return nil return nil
@ -46,22 +48,22 @@ func (p *process_t) push_string_value(val string) error {
func (p *process_t) merge_top_values() error { func (p *process_t) merge_top_values() error {
var new_val string var new_val string
if p.sp < 2 { if p.vsp < 2 {
return fmt.Errorf("stack corrupt") return fmt.Errorf("stack corrupt")
} }
new_val = *(*string)(p.stack[p.sp-2]) + *(*string)(p.stack[p.sp-1]) new_val = *(*string)(p.vstack[p.vsp-2]) + *(*string)(p.vstack[p.vsp-1])
p.sp-- p.vsp--
p.stack[p.sp] = nil p.vstack[p.vsp] = nil
p.stack[p.sp-1] = unsafe.Pointer(&new_val) p.vstack[p.vsp-1] = unsafe.Pointer(&new_val)
p.ctx.count-- p.ctx.count--
return nil return nil
} }
func (p *process_t) pop_value() unsafe.Pointer { func (p *process_t) pop_value() unsafe.Pointer {
var v unsafe.Pointer var v unsafe.Pointer
p.sp-- p.vsp--
v = p.stack[p.sp] v = p.vstack[p.vsp]
p.stack[p.sp] = nil p.vstack[p.vsp] = nil
return v return v
} }
@ -85,11 +87,11 @@ func (p *process_t) call() error {
} }
func (p *process_t) GetCalleeName() *string { func (p *process_t) GetCalleeName() *string {
return (*string)(p.stack[p.sp-p.ctx.count+1]) return (*string)(p.vstack[p.vsp-p.ctx.count+1])
} }
func (p *process_t) GetArg(idx int) unsafe.Pointer { func (p *process_t) GetArg(idx int) unsafe.Pointer {
return (p.stack[p.sp-p.ctx.count+2+idx]) return (p.vstack[p.vsp-p.ctx.count+2+idx])
} }
func (p *process_t) GetNumArgs() int { func (p *process_t) GetNumArgs() int {
@ -97,7 +99,7 @@ func (p *process_t) GetNumArgs() int {
} }
func (p *process_t) Return(val string) { func (p *process_t) Return(val string) {
p.stack[p.sp-p.ctx.count] = unsafe.Pointer(&val) p.vstack[p.vsp-p.ctx.count] = unsafe.Pointer(&val)
} }
func (p *process_t) push_context(node *Cnode_t, container_node *Cnode_t) { func (p *process_t) push_context(node *Cnode_t, container_node *Cnode_t) {
@ -116,11 +118,11 @@ func (p *process_t) pop_context() (*Cnode_t, *Cnode_t) {
// 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++ {
p.stack[p.sp-p.ctx.count+i] = nil p.vstack[p.vsp-p.ctx.count+i] = nil
} }
// pop off the cleaned arguments // pop off the cleaned arguments
p.sp -= p.ctx.count - 1 // keep the return value in the stack p.vsp -= p.ctx.count - 1 // keep the return value in the stack
p.ctx = p.ctx.parent_ctx p.ctx = p.ctx.parent_ctx
if p.ctx != nil { if p.ctx != nil {
@ -144,7 +146,12 @@ func (interp *Interp) eval_node_child(container_node *Cnode_t) (*string, error)
p.interp = interp p.interp = interp
stmt_node = container_node.child stmt_node = container_node.child
fmt.Printf("START p.sp = %d\n", p.sp) //interp.dump_cnodes(container_node, true)
//fmt.Printf("--------------\n")
//interp.dump_cnodes(stmt_node, true)
//fmt.Printf("--------------\n")
fmt.Printf("START p.sp = %d\n", p.vsp)
for stmt_node != nil { for stmt_node != nil {
if stmt_node.code != CNODE_STMT { if stmt_node.code != CNODE_STMT {
panic("internal error - not statement node") panic("internal error - not statement node")
@ -159,7 +166,7 @@ func (interp *Interp) eval_node_child(container_node *Cnode_t) (*string, error)
for inner_node != nil { for inner_node != nil {
switch inner_node.code { switch inner_node.code {
case CNODE_BRACKET: case CNODE_BRACKET:
case CNODE_DQUOTE:
if inner_node.child != nil { if inner_node.child != nil {
stmt_node = inner_node.child // first statement inside [] stmt_node = inner_node.child // first statement inside []
p.push_context(stmt_node, inner_node) p.push_context(stmt_node, inner_node)
@ -170,9 +177,12 @@ func (interp *Interp) eval_node_child(container_node *Cnode_t) (*string, error)
p.push_string_value("") p.push_string_value("")
} }
case CNODE_BRACE:
p.push_cnode_value(inner_node)
case CNODE_TEXT: case CNODE_TEXT:
//fmt.Printf("XXXXXXXXXXXXXXXXXXXx[%s]\n", string(child_node.token)) //fmt.Printf("XXXXXXXXXXXXXXXXXXXx[%s]\n", string(inner_node.token))
err = p.push_string_value(string(inner_node.token)) err = p.push_string_value(string(inner_node.token))
if err != nil { if err != nil {
goto oops goto oops
@ -184,11 +194,15 @@ func (interp *Interp) eval_node_child(container_node *Cnode_t) (*string, error)
inner_node = inner_node.next inner_node = inner_node.next
} }
//fmt.Printf("CALLING\n") fmt.Printf("CALLING for %d\n", p.ctx.parent_node.code)
if p.ctx.parent_node.code == CNODE_STMT {
err = p.call() err = p.call()
if err != nil { if err != nil {
goto oops goto oops
} }
} else {
fmt.Printf("DDDDDDDDDDDDBVVVVVVVVVVVDDDd\n")
}
stmt_node, inner_node = p.pop_context() stmt_node, inner_node = p.pop_context()
if inner_node != nil { if inner_node != nil {
@ -200,7 +214,7 @@ func (interp *Interp) eval_node_child(container_node *Cnode_t) (*string, error)
stmt_node = stmt_node.next stmt_node = stmt_node.next
} }
fmt.Printf("END p.sp = %d\n", p.sp) fmt.Printf("END p.sp = %d\n", p.vsp)
return v, nil return v, nil
oops: oops:
@ -326,7 +340,7 @@ func (interp *Interp) eval_arg(p *process_t, pos int) (*string, error) {
ptr = uintptr(p.GetArg(pos)) ptr = uintptr(p.GetArg(pos))
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))) return interp.eval_node_child((*Cnode_t)(unsafe.Pointer(ptr)))
} else { } else {

View File

@ -42,8 +42,8 @@ type context_t struct {
type process_t struct { type process_t struct {
interp *Interp interp *Interp
stack [16]unsafe.Pointer // value stack - TODO: change size vstack [16]unsafe.Pointer // value stack - TODO: change size
sp int vsp int
ctx *context_t ctx *context_t
} }