implementing the evaluator
This commit is contained in:
parent
379a6e5030
commit
cb130353ce
@ -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 {
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user