still wrong evaluator implementation...
This commit is contained in:
parent
1945452429
commit
9481de61d5
176
interp/eval.go
176
interp/eval.go
@ -5,7 +5,7 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
var debug bool = false
|
var debug bool = true
|
||||||
|
|
||||||
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"}
|
||||||
|
|
||||||
@ -143,7 +143,6 @@ func (p *process_t) pop_context(clear_vstack bool) (*Cnode_t, *Cnode_t) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (interp *Interp) dump_vstack(p *process_t) {
|
func (interp *Interp) dump_vstack(p *process_t) {
|
||||||
//fmt.Printf("DDDDDDDDDDDDBVVVVVVVVVVVDDDd\n")
|
|
||||||
fmt.Printf("p.VSP => %d\n", p.vsp)
|
fmt.Printf("p.VSP => %d\n", p.vsp)
|
||||||
for i := 0; i < p.vsp; i++ {
|
for i := 0; i < p.vsp; i++ {
|
||||||
x := uintptr(p.vstack[i])
|
x := uintptr(p.vstack[i])
|
||||||
@ -158,15 +157,20 @@ func (interp *Interp) dump_vstack(p *process_t) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
[STMT]
|
puts "hello" world
|
||||||
[TEXT] [DQUOTE] [TEXT]
|
|
||||||
|
|
||||||
[STMT]
|
[STMT]
|
||||||
[BRACKET] [TEXT]
|
[TEXT|puts] [DQUOTE] [TEXT|world]
|
||||||
|
[TEXT|hello]
|
||||||
|
|
||||||
|
[puts 1 2; puts 1] 999
|
||||||
|
|
||||||
[STMT]
|
[STMT]
|
||||||
[TEXT] [TEXT] [TEXT]
|
[BRACKET] [TEXT|999]
|
||||||
[STMT]
|
[STMT]
|
||||||
[TEXT] [TEXT]
|
[TEXT|puts] [TEXT|1] [TEXT|2]
|
||||||
|
[STMT]
|
||||||
|
[TEXT|puts] [TEXT|1]
|
||||||
|
|
||||||
"pu[null 1]ts" 10 20
|
"pu[null 1]ts" 10 20
|
||||||
|
|
||||||
@ -181,30 +185,31 @@ func (interp *Interp) eval_stmt_nodes(container_node *Cnode_t) (*string, error)
|
|||||||
p process_t
|
p process_t
|
||||||
v *string
|
v *string
|
||||||
stmt_node *Cnode_t
|
stmt_node *Cnode_t
|
||||||
|
upper_node *Cnode_t
|
||||||
inner_node *Cnode_t
|
inner_node *Cnode_t
|
||||||
|
is_stmt bool
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
v = new(string) // TODO: change new(string) to a const
|
v = new(string) // TODO: change new(string) to a const
|
||||||
|
|
||||||
p.interp = interp
|
p.interp = interp
|
||||||
stmt_node = container_node.child // the first statement
|
upper_node = container_node
|
||||||
|
stmt_node = upper_node.child // the first statement
|
||||||
//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)
|
fmt.Printf("START p.sp = %d\n", p.vsp)
|
||||||
|
|
||||||
for stmt_node != nil {
|
for stmt_node != nil {
|
||||||
|
start_over_0:
|
||||||
if stmt_node.code != CNODE_STMT {
|
if stmt_node.code != CNODE_STMT {
|
||||||
panic("internal error - not statement node")
|
panic("internal error - not statement node")
|
||||||
}
|
}
|
||||||
|
|
||||||
p.push_context(stmt_node, nil)
|
//fmt.Printf("PUSHING CONTEXT.....\n")
|
||||||
|
p.push_context(stmt_node, upper_node)
|
||||||
p.push_string_value("") // placeholder for return value
|
p.push_string_value("") // placeholder for return value
|
||||||
|
|
||||||
start_over:
|
//start_over:
|
||||||
inner_node = stmt_node.child
|
inner_node = stmt_node.child
|
||||||
resume:
|
resume:
|
||||||
for inner_node != nil {
|
for inner_node != nil {
|
||||||
@ -212,15 +217,14 @@ func (interp *Interp) eval_stmt_nodes(container_node *Cnode_t) (*string, error)
|
|||||||
switch inner_node.code {
|
switch inner_node.code {
|
||||||
case CNODE_BRACKET:
|
case CNODE_BRACKET:
|
||||||
if inner_node.child != nil {
|
if inner_node.child != nil {
|
||||||
stmt_node = inner_node.child // first statement inside []
|
upper_node = inner_node
|
||||||
p.push_context(stmt_node, inner_node)
|
stmt_node = upper_node.child
|
||||||
p.push_string_value("") // for return value
|
|
||||||
if debug {
|
if debug {
|
||||||
fmt.Printf("going to start over\n")
|
fmt.Printf("going to start over\n")
|
||||||
interp.dump_cnodes(stmt_node, true)
|
interp.dump_cnodes(stmt_node, true)
|
||||||
fmt.Printf("\n--\n")
|
fmt.Printf("\n--\n")
|
||||||
}
|
}
|
||||||
goto start_over
|
goto start_over_0
|
||||||
} else {
|
} else {
|
||||||
// no statements inside []. treat it like an empty string
|
// no statements inside []. treat it like an empty string
|
||||||
p.push_string_value("")
|
p.push_string_value("")
|
||||||
@ -228,6 +232,7 @@ func (interp *Interp) eval_stmt_nodes(container_node *Cnode_t) (*string, error)
|
|||||||
|
|
||||||
case CNODE_DQUOTE:
|
case CNODE_DQUOTE:
|
||||||
if inner_node.child != nil {
|
if inner_node.child != nil {
|
||||||
|
//fmt.Printf("PUSHING CONTEXT.....\n")
|
||||||
p.push_context(stmt_node, inner_node)
|
p.push_context(stmt_node, inner_node)
|
||||||
//p.push_string_value("") // no placeholder for return value is needed
|
//p.push_string_value("") // no placeholder for return value is needed
|
||||||
inner_node = inner_node.child
|
inner_node = inner_node.child
|
||||||
@ -255,7 +260,6 @@ func (interp *Interp) eval_stmt_nodes(container_node *Cnode_t) (*string, error)
|
|||||||
|
|
||||||
// TODO: many more types...
|
// TODO: many more types...
|
||||||
case CNODE_JOIN:
|
case CNODE_JOIN:
|
||||||
//fmt.Printf("JOIN>>>>>\n")
|
|
||||||
p.merge_top_values()
|
p.merge_top_values()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,9 +269,8 @@ func (interp *Interp) eval_stmt_nodes(container_node *Cnode_t) (*string, error)
|
|||||||
if debug {
|
if debug {
|
||||||
interp.dump_vstack(&p)
|
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)
|
//fmt.Printf("p.ctx.parent_node.code %d p.ctx.container_node.code %d CNODE_STMT %d CNODE_DQUOTE %d CNODE_BRACKET %d\n", p.ctx.parent_node.code, p.ctx.container_node.code, CNODE_STMT, CNODE_DQUOTE, CNODE_BRACKET)
|
||||||
//if p.ctx.parent_node.code == CNODE_STMT {
|
if p.ctx.container_node.code == CNODE_INIT || p.ctx.container_node.code == CNODE_BRACKET {
|
||||||
if p.ctx.container_node == nil || (p.ctx.container_node.code == CNODE_STMT || p.ctx.container_node.code == CNODE_BRACKET) {
|
|
||||||
if debug {
|
if debug {
|
||||||
fmt.Printf("calling..... [%s]\n", *p.GetCalleeName())
|
fmt.Printf("calling..... [%s]\n", *p.GetCalleeName())
|
||||||
}
|
}
|
||||||
@ -276,20 +279,26 @@ func (interp *Interp) eval_stmt_nodes(container_node *Cnode_t) (*string, error)
|
|||||||
goto oops
|
goto oops
|
||||||
}
|
}
|
||||||
|
|
||||||
stmt_node, inner_node = p.pop_context(true)
|
is_stmt = true
|
||||||
} else {
|
} else {
|
||||||
stmt_node, inner_node = p.pop_context(false)
|
is_stmt = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if inner_node != nil {
|
//fmt.Printf("POPPING CONTEXT.....is_stmt[%v]\n", is_stmt)
|
||||||
|
stmt_node, upper_node = p.pop_context(is_stmt)
|
||||||
|
if upper_node != container_node {
|
||||||
if debug {
|
if debug {
|
||||||
fmt.Printf("resuming... %d\n", p.vsp)
|
fmt.Printf("resuming... %d upper_node.next %p\n", p.vsp, upper_node.next)
|
||||||
}
|
}
|
||||||
inner_node = inner_node.next
|
inner_node = upper_node.next // as if it hit the bottom of the innner for loop
|
||||||
goto resume
|
goto resume
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//fmt.Printf("POPPING VALUE...\n")
|
||||||
v = (*string)(p.pop_value()) // get the return value of the statement.
|
v = (*string)(p.pop_value()) // get the return value of the statement.
|
||||||
|
if debug {
|
||||||
|
interp.dump_vstack(&p)
|
||||||
|
}
|
||||||
stmt_node = stmt_node.next
|
stmt_node = stmt_node.next
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,117 +312,6 @@ oops:
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
func (interp *Interp) eval_atom_node_old(node *Cnode_t) (*string, error) {
|
|
||||||
|
|
||||||
var (
|
|
||||||
p process_t
|
|
||||||
v *string
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
|
|
||||||
p.interp = interp
|
|
||||||
p.push_context(nil)
|
|
||||||
p.push_string_value("") // placeholder for return value
|
|
||||||
|
|
||||||
for node != nil {
|
|
||||||
switch node.code {
|
|
||||||
case CNODE_BRACKET: // this is a container
|
|
||||||
if node.child != nil {
|
|
||||||
p.push_context(node)
|
|
||||||
err = p.push_string_value("") // placeholder for return value
|
|
||||||
if err != nil {
|
|
||||||
goto oops
|
|
||||||
}
|
|
||||||
node = node.child
|
|
||||||
continue
|
|
||||||
} else {
|
|
||||||
err = p.push_string_value("")
|
|
||||||
if err != nil {
|
|
||||||
goto oops
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case CNODE_BRACE: // this is a container
|
|
||||||
err = p.push_cnode_value(node)
|
|
||||||
if err != nil {
|
|
||||||
goto oops
|
|
||||||
}
|
|
||||||
|
|
||||||
case CNODE_DQUOTE: // this is a container
|
|
||||||
// TODO: at the feed layer, recompose CNODE_DQUOTE item to
|
|
||||||
// successive ATOM item
|
|
||||||
// "abc $ddd [xx 11]" must be TEXT("abc ") + VAR("ddd") + BRACKET["xx 11"] without SEP in between
|
|
||||||
|
|
||||||
// this is not right.....
|
|
||||||
if node.child != nil {
|
|
||||||
// TODO: something is not right here. handle inner stuffs
|
|
||||||
//fmt.Printf("pushing [%s]\n", string(node.child.token))
|
|
||||||
err = p.push_string_value(string(node.child.token))
|
|
||||||
} else {
|
|
||||||
err = p.push_string_value("")
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
goto oops
|
|
||||||
}
|
|
||||||
|
|
||||||
case CNODE_VAR:
|
|
||||||
|
|
||||||
case CNODE_TEXT:
|
|
||||||
//fmt.Printf("pushing [%s]\n", string(node.token))
|
|
||||||
err = p.push_string_value(string(node.token))
|
|
||||||
if err != nil {
|
|
||||||
goto oops
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
err = fmt.Errorf("internal error - non-atom node - %d", node.code)
|
|
||||||
goto oops
|
|
||||||
}
|
|
||||||
|
|
||||||
node = node.next
|
|
||||||
check_end:
|
|
||||||
if node == nil { // reached the last node
|
|
||||||
err = p.call()
|
|
||||||
if err != nil {
|
|
||||||
goto oops
|
|
||||||
}
|
|
||||||
if p.ctx.parent_ctx != nil {
|
|
||||||
node = p.pop_context()
|
|
||||||
if node.seqno > 0 {
|
|
||||||
// merge the top 2 values (return from [] + previous argument)
|
|
||||||
// for instance, the expression `aa[qq 11]` must product a single word
|
|
||||||
// `aa` concatenated of the result of `qq 11`
|
|
||||||
err = p.merge_top_values()
|
|
||||||
if err != nil {
|
|
||||||
goto oops
|
|
||||||
}
|
|
||||||
}
|
|
||||||
node = node.next
|
|
||||||
|
|
||||||
// take `aa 11 22 [dd [bb cc]]` as an example
|
|
||||||
// after [bb cc] is called, it must call `[dd]`` followed by `aa`.
|
|
||||||
// this goto loop is to handle successive calls when a nested call is the
|
|
||||||
// last argument
|
|
||||||
goto check_end
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
v = (*string)(p.pop_value())
|
|
||||||
p.pop_context()
|
|
||||||
if p.ctx != nil {
|
|
||||||
err = fmt.Errorf("internal error - dangling process context")
|
|
||||||
goto oops
|
|
||||||
}
|
|
||||||
|
|
||||||
return v, nil
|
|
||||||
|
|
||||||
oops:
|
|
||||||
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 (
|
||||||
ptr uintptr
|
ptr uintptr
|
||||||
|
Loading…
Reference in New Issue
Block a user