just more code
This commit is contained in:
parent
6ffe32a9df
commit
ca5c1efd8a
28
bin/main.go
28
bin/main.go
@ -76,34 +76,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
fmt.Printf("RETURN VALUE = [%s]\n", *v.(*string))
|
fmt.Printf("RETURN VALUE = [%s]\n", *v.(*string))
|
||||||
|
|
||||||
/*
|
|
||||||
err = interp.FeedRunes([]rune(`
|
|
||||||
proc inc{x} {
|
|
||||||
puts {10 20}
|
|
||||||
return [expr $x + 1]
|
|
||||||
}
|
|
||||||
\{abc 11 2\ \1011 \ 2\x65 \uBc29\uaD6cdefg\uZZ\xZZ\U0000BC29\UAD6cZZ \
|
|
||||||
[donkey 1 [expr [expr 2 + 3] + 3] ]
|
|
||||||
hello { world { }man}
|
|
||||||
"command { l a n g }"
|
|
||||||
set a [puts "1111" "22 22" "3333 [expr "123" + 2] 4444"]
|
|
||||||
abc [expr [expr 2 + "4[expr 2 * 6]"] + 9]
|
|
||||||
puts $a ${ kkk qqq }
|
|
||||||
puts "\x65\ubc29\n"
|
|
||||||
{}`))
|
|
||||||
*/
|
|
||||||
//err = interp.FeedRunes([]rune(`hello [world [1 9] 2]
|
|
||||||
//`))
|
|
||||||
/*
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("ERROR %s\n", err)
|
|
||||||
} else {
|
|
||||||
err = interp.EndFeed()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("ERROR %s\n", err)
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
interp.Close()
|
interp.Close()
|
||||||
f.Close()
|
f.Close()
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
var debug bool = false
|
var debug bool = false
|
||||||
|
|
||||||
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"}
|
||||||
|
var empty_string = ""
|
||||||
|
|
||||||
/*
|
/*
|
||||||
value stack (p.vstack)
|
value stack (p.vstack)
|
||||||
@ -20,6 +21,27 @@ var err_num_args *error_t = &error_t{msg: "wrong number of arguments"}
|
|||||||
evaluation stack (p.ctx)
|
evaluation stack (p.ctx)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
func (p *process_t) push_call_frame() {
|
||||||
|
var cf *call_frame_t
|
||||||
|
|
||||||
|
cf = &call_frame_t{}
|
||||||
|
if p.cframe == nil {
|
||||||
|
// let it point to the global frame located in the interp struct
|
||||||
|
cf.parent = p.interp.cframe
|
||||||
|
} else {
|
||||||
|
cf.parent = p.cframe
|
||||||
|
}
|
||||||
|
p.cframe = cf
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *process_t) pop_call_frame() {
|
||||||
|
if p.cframe == p.interp.cframe {
|
||||||
|
p.cframe = nil
|
||||||
|
} else {
|
||||||
|
p.cframe = p.cframe.parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (p *process_t) push_cnode_value(val *Cnode_t) error {
|
func (p *process_t) push_cnode_value(val *Cnode_t) error {
|
||||||
if p.vsp >= cap(p.vstack) {
|
if p.vsp >= cap(p.vstack) {
|
||||||
return fmt.Errorf("stack full")
|
return fmt.Errorf("stack full")
|
||||||
@ -48,13 +70,25 @@ 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
|
||||||
var v1, v2 *string
|
var v1, v2 *string
|
||||||
|
var ok1, ok2 bool
|
||||||
|
|
||||||
if p.vsp < 2 {
|
if p.vsp < 2 {
|
||||||
return fmt.Errorf("stack corrupt")
|
return fmt.Errorf("stack corrupt")
|
||||||
}
|
}
|
||||||
|
|
||||||
v1, _ = p.vstack[p.vsp-2].(*string)
|
v1, ok1 = p.vstack[p.vsp-2].(*string)
|
||||||
v2, _ = p.vstack[p.vsp-1].(*string)
|
v2, ok2 = p.vstack[p.vsp-1].(*string)
|
||||||
|
|
||||||
|
if !ok1 {
|
||||||
|
// TODO: correct this to get the original text inside{}
|
||||||
|
// or must panic here by making {} unmergable in the feeder side
|
||||||
|
v1 = &empty_string
|
||||||
|
}
|
||||||
|
if !ok2 {
|
||||||
|
// TODO: correct this to get the original text inside {}
|
||||||
|
// or must panic here by making {} unmergable in the feeder side
|
||||||
|
v2 = &empty_string
|
||||||
|
}
|
||||||
//new_val = *(*string)(p.vstack[p.vsp-2]) + *(*string)(p.vstack[p.vsp-1])
|
//new_val = *(*string)(p.vstack[p.vsp-2]) + *(*string)(p.vstack[p.vsp-1])
|
||||||
new_val = *v1 + *v2
|
new_val = *v1 + *v2
|
||||||
p.vsp--
|
p.vsp--
|
||||||
@ -90,6 +124,10 @@ func (p *process_t) call() error {
|
|||||||
|
|
||||||
// TODO: use a map
|
// TODO: use a map
|
||||||
switch *callee {
|
switch *callee {
|
||||||
|
case "proc":
|
||||||
|
proc = proc_proc
|
||||||
|
case "set":
|
||||||
|
proc = proc_set
|
||||||
case "if":
|
case "if":
|
||||||
proc = proc_if
|
proc = proc_if
|
||||||
case "puts":
|
case "puts":
|
||||||
@ -216,9 +254,8 @@ puts "hello" world
|
|||||||
[STMT]
|
[STMT]
|
||||||
[TEXT|null] [TEXT|1]
|
[TEXT|null] [TEXT|1]
|
||||||
*/
|
*/
|
||||||
func (interp *Interp) eval_stmt_nodes(container_node *Cnode_t) (Value_t, error) {
|
func (interp *Interp) eval_stmt_nodes(p *process_t, container_node *Cnode_t) (Value_t, error) {
|
||||||
var (
|
var (
|
||||||
p process_t
|
|
||||||
v Value_t
|
v Value_t
|
||||||
stmt_node *Cnode_t
|
stmt_node *Cnode_t
|
||||||
upper_node *Cnode_t
|
upper_node *Cnode_t
|
||||||
@ -230,7 +267,6 @@ func (interp *Interp) eval_stmt_nodes(container_node *Cnode_t) (Value_t, error)
|
|||||||
|
|
||||||
v = new(string) // TODO: change new(string) to a const
|
v = new(string) // TODO: change new(string) to a const
|
||||||
|
|
||||||
p.interp = interp
|
|
||||||
upper_node = container_node
|
upper_node = container_node
|
||||||
stmt_node = upper_node.child // the first statement
|
stmt_node = upper_node.child // the first statement
|
||||||
|
|
||||||
@ -310,7 +346,7 @@ func (interp *Interp) eval_stmt_nodes(container_node *Cnode_t) (Value_t, 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 CNODE_BRACKET %d\n", p.ctx.parent_node.code, p.ctx.container_node.code, CNODE_STMT, CNODE_DQUOTE, CNODE_BRACKET)
|
//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.container_node.code == CNODE_INIT || p.ctx.container_node.code == CNODE_BRACKET || p.ctx.container_node.code == CNODE_BRACE {
|
if p.ctx.container_node.code == CNODE_INIT || p.ctx.container_node.code == CNODE_BRACKET || p.ctx.container_node.code == CNODE_BRACE {
|
||||||
@ -363,21 +399,21 @@ func (interp *Interp) eval_stmt_nodes(container_node *Cnode_t) (Value_t, error)
|
|||||||
|
|
||||||
v = p.pop_value() // get the return value of the statement.
|
v = p.pop_value() // get the return value of the statement.
|
||||||
if debug {
|
if debug {
|
||||||
interp.dump_vstack(&p)
|
interp.dump_vstack(p)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
v = p.pop_value() // get the return value of the statement.
|
v = p.pop_value() // get the return value of the statement.
|
||||||
if debug {
|
if debug {
|
||||||
interp.dump_vstack(&p)
|
interp.dump_vstack(p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
|
||||||
if debug {
|
if debug {
|
||||||
interp.dump_vstack(&p)
|
interp.dump_vstack(p)
|
||||||
fmt.Printf("END p.sp = %d\n", p.vsp)
|
fmt.Printf("END p.sp = %d\n", p.vsp)
|
||||||
}
|
}
|
||||||
if p.vsp != org_vsp {
|
if p.vsp != org_vsp {
|
||||||
@ -410,7 +446,7 @@ func (interp *Interp) eval_arg(p *process_t, pos int) (Value_t, error) {
|
|||||||
case *string:
|
case *string:
|
||||||
return t, nil
|
return t, nil
|
||||||
case *Cnode_t:
|
case *Cnode_t:
|
||||||
return interp.eval_stmt_nodes(t)
|
return interp.eval_stmt_nodes(p, t)
|
||||||
default:
|
default:
|
||||||
panic("internal error - argument type unrecognized")
|
panic("internal error - argument type unrecognized")
|
||||||
}
|
}
|
||||||
@ -444,6 +480,12 @@ func (interp *Interp) eval_arg_literally(p *process_t, pos int) (Value_t, error)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (interp *Interp) set_var(p *process_t, name Value_t, val Value_t) error {
|
||||||
|
//var err error_t
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (interp *Interp) EvalText(text []rune) (Value_t, error) {
|
func (interp *Interp) EvalText(text []rune) (Value_t, error) {
|
||||||
var (
|
var (
|
||||||
v Value_t
|
v Value_t
|
||||||
|
@ -46,6 +46,7 @@ type process_t struct {
|
|||||||
vstack [16]Value_t // value stack - TODO: change size
|
vstack [16]Value_t // value stack - TODO: change size
|
||||||
vsp int
|
vsp int
|
||||||
ctx *context_t
|
ctx *context_t
|
||||||
|
cframe *call_frame_t
|
||||||
}
|
}
|
||||||
|
|
||||||
type call_frame_t struct {
|
type call_frame_t struct {
|
||||||
@ -107,7 +108,6 @@ type Cnode_t struct {
|
|||||||
next *Cnode_t
|
next *Cnode_t
|
||||||
child *Cnode_t // for container nodes
|
child *Cnode_t // for container nodes
|
||||||
code cnode_code_t
|
code cnode_code_t
|
||||||
seqno int
|
|
||||||
token []rune
|
token []rune
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ type Interp struct {
|
|||||||
max_level int
|
max_level int
|
||||||
|
|
||||||
feed *feed_struct_t
|
feed *feed_struct_t
|
||||||
call_frame *call_frame_t
|
cframe *call_frame_t
|
||||||
result string
|
result string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,10 +139,15 @@ func NewInterp(max_level int, strict bool) (*Interp, error) {
|
|||||||
interp.push_feed_struct(FEED_TOP)
|
interp.push_feed_struct(FEED_TOP)
|
||||||
interp.push_feed_struct(FEED_INIT)
|
interp.push_feed_struct(FEED_INIT)
|
||||||
|
|
||||||
|
// global cframe?
|
||||||
|
interp.cframe = &call_frame_t{}
|
||||||
|
|
||||||
return interp, nil
|
return interp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (interp *Interp) Close() {
|
func (interp *Interp) Close() {
|
||||||
|
interp.cframe = nil
|
||||||
|
|
||||||
for interp.feed != nil {
|
for interp.feed != nil {
|
||||||
interp.pop_feed_struct()
|
interp.pop_feed_struct()
|
||||||
}
|
}
|
||||||
@ -234,8 +239,11 @@ func (interp *Interp) Execute(node_head *Cnode_t) (Value_t, error) {
|
|||||||
node *Cnode_t
|
node *Cnode_t
|
||||||
v Value_t
|
v Value_t
|
||||||
err error
|
err error
|
||||||
|
p process_t
|
||||||
)
|
)
|
||||||
|
|
||||||
|
p = process_t{interp: interp, vsp: 0}
|
||||||
|
|
||||||
v = new(string) // if there is no code the execute, the return value is an empty string
|
v = new(string) // if there is no code the execute, the return value is an empty string
|
||||||
|
|
||||||
for node = node_head; node != nil; node = node.next {
|
for node = node_head; node != nil; node = node.next {
|
||||||
@ -248,7 +256,7 @@ func (interp *Interp) Execute(node_head *Cnode_t) (Value_t, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//v, err = interp.eval_node_child(node.child)
|
//v, err = interp.eval_node_child(node.child)
|
||||||
v, err = interp.eval_stmt_nodes(node)
|
v, err = interp.eval_stmt_nodes(&p, node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,65 @@ package interp
|
|||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
|
func proc_proc(p *process_t) error {
|
||||||
|
/*
|
||||||
|
p.push_call_frame()
|
||||||
|
p.set_var("aaa", 10)
|
||||||
|
p.set_var("bbb", 20)
|
||||||
|
p.eval_stmt_nodes()
|
||||||
|
p.pop_call_frame()
|
||||||
|
*/
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if p.GetNumArgs() != 3 {
|
||||||
|
err = err_num_args
|
||||||
|
goto done
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// procedure name
|
||||||
|
v1, err = p.interp.eval_arg(p, 0)
|
||||||
|
if err != nil {
|
||||||
|
goto done
|
||||||
|
}
|
||||||
|
|
||||||
|
p.set_var(p, v1, v2)*/
|
||||||
|
done:
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func proc_set(p *process_t) error {
|
||||||
|
var (
|
||||||
|
v1, v2 Value_t
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
if p.GetNumArgs() != 2 {
|
||||||
|
err = err_num_args
|
||||||
|
goto done
|
||||||
|
}
|
||||||
|
|
||||||
|
v1, err = p.interp.eval_arg(p, 0)
|
||||||
|
if err != nil {
|
||||||
|
goto done
|
||||||
|
}
|
||||||
|
|
||||||
|
v2, err = p.interp.eval_arg(p, 1)
|
||||||
|
if err != nil {
|
||||||
|
goto done
|
||||||
|
}
|
||||||
|
|
||||||
|
err = p.interp.set_var(p, v1, v2)
|
||||||
|
if err != nil {
|
||||||
|
goto done
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Return(v2)
|
||||||
|
|
||||||
|
done:
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func proc_expr(p *process_t) error {
|
func proc_expr(p *process_t) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
Loading…
Reference in New Issue
Block a user