package eval
import (
)
type Frame struct {
Evaler *Evaler
srcMeta parse.Source
local, up *Ns
intCh <-chan struct{}
ports []*Port
traceback *StackTrace
background bool
}
func ( *Frame) ( parse.Source, diag.Ranger, *Ns) (*Ns, func() Exception, error) {
, := parse.Parse(, parse.Config{WarningWriter: .ErrorFile()})
if != nil {
return nil, nil,
}
:= .local
if != nil {
=
}
:= .traceback
if != nil {
= .addTraceback()
}
:= &Frame{
.Evaler, , , new(Ns), .intCh, .ports, , .background}
, := compile(.Evaler.Builtin().static(), .static(), , .ErrorFile())
if != nil {
return nil, nil,
}
, := .prepare()
return , , nil
}
func ( *Frame) ( parse.Source, diag.Ranger, *Ns) (*Ns, error) {
, , := .PrepareEval(, , )
if != nil {
return nil,
}
return , ()
}
func ( *Frame) () error {
for , := range .ports {
.close()
}
return nil
}
func ( *Frame) () chan interface{} {
return .ports[0].Chan
}
func ( *Frame) () *os.File {
return .ports[0].File
}
func ( *Frame) () chan<- interface{} {
return .ports[1].Chan
}
func ( *Frame) () *os.File {
return .ports[1].File
}
func ( *Frame) () *os.File {
return .ports[2].File
}
func ( *Frame) ( func(interface{})) {
var sync.WaitGroup
:= make(chan interface{})
.Add(2)
go func() {
linesToChan(.InputFile(), )
.Done()
}()
go func() {
for := range .ports[0].Chan {
<-
}
.Done()
}()
go func() {
.Wait()
close()
}()
for := range {
()
}
}
func ( io.Reader, chan<- interface{}) {
:= bufio.NewReader()
for {
, := .ReadString('\n')
if != "" {
<- strutil.ChopLineEnding()
}
if != nil {
if != io.EOF {
logger.Println("error on reading:", )
}
break
}
}
}
func ( *Frame) ( string) *Frame {
:= make([]*Port, len(.ports))
for , := range .ports {
if != nil {
[] = .fork()
}
}
return &Frame{
.Evaler, .srcMeta,
.local, .up,
.intCh, ,
.traceback, .background,
}
}
func ( *Frame) ( string, *Port) *Frame {
:= .fork()
.ports[1] =
return
}
func ( *Frame) ( func(*Frame) error) ([]interface{}, error) {
, , := CapturePort()
if != nil {
return nil,
}
= (.forkWithOutput("[output capture]", ))
return (),
}
func ( *Frame) ( func(*Frame) error, func(<-chan interface{}), func(*os.File)) error {
, , := PipePort(, )
if != nil {
return
}
= (.forkWithOutput("[output pipe]", ))
()
return
}
func ( *Frame) ( diag.Ranger) *StackTrace {
return &StackTrace{
Head: diag.NewContext(.srcMeta.Name, .srcMeta.Code, .Range()),
Next: .traceback,
}
}
func ( *Frame) ( diag.Ranger, error) Exception {
switch e := .(type) {
case nil:
return nil
case Exception:
return
default:
:= diag.NewContext(.srcMeta.Name, .srcMeta.Code, )
if , := .(errs.SetReadOnlyVar); {
= errs.SetReadOnlyVar{VarName: .RelevantString()}
}
return &exception{, &StackTrace{Head: , Next: .traceback}}
}
}
func ( *Frame) ( diag.Ranger, string, ...interface{}) Exception {
return .errorp(, fmt.Errorf(, ...))
}
func ( *Frame) ( string, *diag.Context, int) {
if prog.DeprecationLevel < {
return
}
if == nil {
fmt.Fprintf(.ErrorFile(), "deprecation: \033[31;1m%s\033[m\n", )
return
}
if .Evaler.registerDeprecation(deprecation{.Name, .Ranging, }) {
:= diag.Error{Type: "deprecation", Message: , Context: *}
.ErrorFile().WriteString(.Show("") + "\n")
}
}