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))
|
||||
|
||||
/*
|
||||
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()
|
||||
f.Close()
|
||||
os.Exit(0)
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
var debug bool = false
|
||||
|
||||
var err_num_args *error_t = &error_t{msg: "wrong number of arguments"}
|
||||
var empty_string = ""
|
||||
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
|
||||
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 {
|
||||
if p.vsp >= cap(p.vstack) {
|
||||
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 {
|
||||
var new_val string
|
||||
var v1, v2 *string
|
||||
var ok1, ok2 bool
|
||||
|
||||
if p.vsp < 2 {
|
||||
return fmt.Errorf("stack corrupt")
|
||||
}
|
||||
|
||||
v1, _ = p.vstack[p.vsp-2].(*string)
|
||||
v2, _ = p.vstack[p.vsp-1].(*string)
|
||||
v1, ok1 = p.vstack[p.vsp-2].(*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 = *v1 + *v2
|
||||
p.vsp--
|
||||
@ -90,6 +124,10 @@ func (p *process_t) call() error {
|
||||
|
||||
// TODO: use a map
|
||||
switch *callee {
|
||||
case "proc":
|
||||
proc = proc_proc
|
||||
case "set":
|
||||
proc = proc_set
|
||||
case "if":
|
||||
proc = proc_if
|
||||
case "puts":
|
||||
@ -216,9 +254,8 @@ puts "hello" world
|
||||
[STMT]
|
||||
[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 (
|
||||
p process_t
|
||||
v Value_t
|
||||
stmt_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
|
||||
|
||||
p.interp = interp
|
||||
upper_node = container_node
|
||||
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 {
|
||||
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)
|
||||
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.
|
||||
if debug {
|
||||
interp.dump_vstack(&p)
|
||||
interp.dump_vstack(p)
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
v = p.pop_value() // get the return value of the statement.
|
||||
if debug {
|
||||
interp.dump_vstack(&p)
|
||||
interp.dump_vstack(p)
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
if debug {
|
||||
interp.dump_vstack(&p)
|
||||
interp.dump_vstack(p)
|
||||
fmt.Printf("END p.sp = %d\n", p.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:
|
||||
return t, nil
|
||||
case *Cnode_t:
|
||||
return interp.eval_stmt_nodes(t)
|
||||
return interp.eval_stmt_nodes(p, t)
|
||||
default:
|
||||
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) {
|
||||
var (
|
||||
v Value_t
|
||||
|
@ -46,6 +46,7 @@ type process_t struct {
|
||||
vstack [16]Value_t // value stack - TODO: change size
|
||||
vsp int
|
||||
ctx *context_t
|
||||
cframe *call_frame_t
|
||||
}
|
||||
|
||||
type call_frame_t struct {
|
||||
@ -107,7 +108,6 @@ type Cnode_t struct {
|
||||
next *Cnode_t
|
||||
child *Cnode_t // for container nodes
|
||||
code cnode_code_t
|
||||
seqno int
|
||||
token []rune
|
||||
}
|
||||
|
||||
@ -116,9 +116,9 @@ type Interp struct {
|
||||
level int
|
||||
max_level int
|
||||
|
||||
feed *feed_struct_t
|
||||
call_frame *call_frame_t
|
||||
result string
|
||||
feed *feed_struct_t
|
||||
cframe *call_frame_t
|
||||
result string
|
||||
}
|
||||
|
||||
func NewInterp(max_level int, strict bool) (*Interp, error) {
|
||||
@ -139,10 +139,15 @@ func NewInterp(max_level int, strict bool) (*Interp, error) {
|
||||
interp.push_feed_struct(FEED_TOP)
|
||||
interp.push_feed_struct(FEED_INIT)
|
||||
|
||||
// global cframe?
|
||||
interp.cframe = &call_frame_t{}
|
||||
|
||||
return interp, nil
|
||||
}
|
||||
|
||||
func (interp *Interp) Close() {
|
||||
interp.cframe = nil
|
||||
|
||||
for interp.feed != nil {
|
||||
interp.pop_feed_struct()
|
||||
}
|
||||
@ -234,8 +239,11 @@ func (interp *Interp) Execute(node_head *Cnode_t) (Value_t, error) {
|
||||
node *Cnode_t
|
||||
v Value_t
|
||||
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
|
||||
|
||||
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_stmt_nodes(node)
|
||||
v, err = interp.eval_stmt_nodes(&p, node)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -2,6 +2,65 @@ package interp
|
||||
|
||||
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 {
|
||||
|
||||
return nil
|
||||
|
Loading…
Reference in New Issue
Block a user