just more code

This commit is contained in:
hyung-hwan 2023-08-09 00:57:19 +09:00
parent 6ffe32a9df
commit ca5c1efd8a
4 changed files with 124 additions and 43 deletions

View File

@ -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)

View File

@ -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

View File

@ -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
} }

View File

@ -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