Skip to content

Commit

Permalink
Merge pull request #132 from goplus/eval_const
Browse files Browse the repository at this point in the history
repl: eval const
  • Loading branch information
visualfc authored Jul 7, 2022
2 parents ebda9f3 + 098b1c1 commit e0f25fb
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 43 deletions.
13 changes: 6 additions & 7 deletions constant/constant.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,8 @@ func ExactConstantEx(c constant.Value, toFloat bool) (s string, exact bool) {
if !ok {
panic(fmt.Errorf("parser rat %q error", s))
}
if v, ok := r.Float64(); ok {
return fmt.Sprintf("%v", v), false
}
return r.FloatString(10), false
v, _ := r.Float64()
return fmt.Sprintf("%v", v), false
}
return s, true
}
Expand All @@ -76,9 +74,10 @@ func ExactConstantEx(c constant.Value, toFloat bool) (s string, exact bool) {
}
return s, true
case constant.Complex:
re, e1 := ExactConstantEx(constant.Real(c), toFloat)
im, e2 := ExactConstantEx(constant.Imag(c), toFloat)
return fmt.Sprintf("%v+%vi", re, im), e1 && e2
return c.ExactString(), true
// re, e1 := ExactConstantEx(constant.Real(c), toFloat)
// im, e2 := ExactConstantEx(constant.Imag(c), toFloat)
// return fmt.Sprintf("%v+%vi", re, im), e1 && e2
default:
panic("unreachable")
}
Expand Down
85 changes: 49 additions & 36 deletions repl.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ package igop
import (
"fmt"
"go/ast"
"go/constant"
"go/scanner"
"go/token"
"go/types"
"strconv"
"strings"

xconst "github.com/goplus/igop/constant"
"golang.org/x/tools/go/ssa"
)

Expand Down Expand Up @@ -128,6 +129,7 @@ func main() {
func (r *Repl) eval(tok token.Token, expr string) (err error) {
var src string
var inMain bool
var evalConst bool
switch tok {
case token.PACKAGE:
// skip package
Expand Down Expand Up @@ -192,11 +194,15 @@ func (r *Repl) eval(tok token.Token, expr string) (err error) {
fixed = append(fixed, "__igop_repl_used__(&"+v+")")
// fixed = append(fixed, "__igop_repl_dump__("+v+")")
} else if strings.HasSuffix(e.Msg, errIsNotUsed) {
if c, ok := extractConstant([]byte(e.Msg[:len(e.Msg)-len(errIsNotUsed)])); ok {
r.lastDump = []string{c.Lit}
return nil
if _, ok := extractConstant([]byte(e.Msg[:len(e.Msg)-len(errIsNotUsed)])); ok {
// r.lastDump = []string{c.Lit}
// return nil
expr = "const __igop_repl_const__ = " + expr
tok = token.CONST
evalConst = true
} else {
expr = "__igop_repl_dump__(" + expr + ")"
}
expr = "__igop_repl_dump__(" + expr + ")"
} else {
return e
}
Expand All @@ -210,16 +216,44 @@ func (r *Repl) eval(tok token.Token, expr string) (err error) {
if err != nil {
return err
}
err = r.run()
i, err := newInterp(r.ctx, r.pkg, r.globalMap)
if err != nil {
return err
}
rinit, err := r.runFunc(i, "init", r.fsInit)
if err == nil {
if inMain {
r.infuncs = append(r.infuncs, expr)
rinit.pc--
}
rmain, err := r.runFunc(i, "main", r.fsMain)
if err != nil {
return err
}
if evalConst {
m, _ := i.mainpkg.Members["__igop_repl_const__"]
c, _ := m.(*ssa.NamedConst)
s, _ := xconst.ExactConstantEx(c.Value.Value, true)
kind := c.Value.Value.Kind()
if kind == constant.Float {
es := c.Value.Value.ExactString()
r.lastDump = []string{fmt.Sprintf("%v %v\n(%v)", s, c.Type(), es)}
} else {
r.globals = append(r.globals, expr)
r.lastDump = []string{fmt.Sprintf("%v %v", s, c.Type())}
}
r.source = src
return nil
}
r.interp = i
r.fsInit = rinit
r.fsMain = rmain
for k, v := range i.globals {
r.globalMap[k.String()] = v
}
return err
if inMain {
r.infuncs = append(r.infuncs, expr)
} else {
r.globals = append(r.globals, expr)
}
r.source = src
return nil
}

const (
Expand Down Expand Up @@ -261,28 +295,6 @@ func (r *Repl) firstToken(src string) token.Token {
return tok
}

func (repl *Repl) run() error {
i, err := newInterp(repl.ctx, repl.pkg, repl.globalMap)
if err != nil {
return err
}
rinit, err := repl.runFunc(i, "init", repl.fsInit)
if err == nil {
repl.fsInit = rinit
repl.fsInit.pc--
}
rmain, err := repl.runFunc(i, "main", repl.fsMain)
if err != nil {
return err
}
repl.fsMain = rmain
repl.interp = i
for k, v := range i.globals {
repl.globalMap[k.String()] = v
}
return nil
}

type fnState struct {
fr *frame
pc int
Expand Down Expand Up @@ -375,10 +387,11 @@ func extractConstant(src []byte) (constant *tokenLit, ok bool) {
case token.INT:
return nodes[0], true
case token.FLOAT:
return nodes[0], true
// extract if not parse float64
if _, err := strconv.ParseFloat(nodes[0].Lit, 128); err != nil {
return nodes[0], true
}
// if _, err := strconv.ParseFloat(nodes[0].Lit, 128); err != nil {
// return nodes[0], true
// }
}
default:
last := nodes[len(nodes)-1]
Expand Down

0 comments on commit e0f25fb

Please sign in to comment.