func addChunk(state *State, chunk Chunk) {
	chunks, ok := state.chunks[state.lineNum]
	if !ok {
		chunks = []Chunk{}
	}
	state.chunks[state.lineNum] = append(chunks, chunk)
	state.lineNum += chunk.numNL
}
add a chunk to the current line in state.chunks
package eval
import (
	"fmt"
	"io"
	"os"
	"os/exec"
	"path"
	"regexp"
	"strings"
)
var (
	builtinPkgs map[string]string
)
func init() {
	builtinPkgs = make(map[string]string)
	pkgs := []string{
		"hash/adler32", "crypto/aes", "encoding/ascii85", "encoding/asn1",
		"go/ast", "sync/atomic", "encoding/base32", "encoding/base64",
		"math/big", "encoding/binary", "bufio", "go/build",
		"bytes", "compress/bzip2", "net/http/cgi", "runtime/cgo",
		"crypto/cipher", "math/cmplx", "image/color", "hash/crc32",
		"hash/crc64", "crypto", "encoding/csv", "runtime/debug",
		"crypto/des", "go/doc", "image/draw", "database/sql/driver",
		"crypto/dsa", "debug/dwarf", "crypto/ecdsa", "debug/elf",
		"crypto/elliptic", "errors", "os/exec", "expvar",
		"net/http/fcgi", "path/filepath", "flag", "compress/flate",
		"fmt", "hash/fnv", "image/gif", "encoding/gob",
		"debug/gosym", "compress/gzip", "hash", "container/heap",
		"encoding/hex", "crypto/hmac", "html", "net/http",
		"net/http/httputil", "image", "io", "io/ioutil",
		"image/jpeg", "encoding/json", "net/rpc/jsonrpc", "container/list",
		"log", "compress/lzw", "debug/macho", "net/mail",
		"math", "crypto/md5", "mime", "mime/multipart",
		"net", "os", "text/template/parse", "go/parser",
		"path", "debug/pe", "encoding/pem", "crypto/x509/pkix",
		"image/png", "net/http/pprof", "go/printer",
		"math/rand", "crypto/rc4", "reflect",
		"regexp", "container/ring", "net/rpc", "crypto/rsa",
		"runtime", "text/scanner", "crypto/sha1",
		"crypto/sha256", "crypto/sha512", "os/signal", "net/smtp",
		"sort", "database/sql", "strconv", "strings",
		"crypto/subtle", "index/suffixarray", "sync", "regexp/syntax",
		"syscall", "log/syslog", "text/tabwriter", "archive/tar",
		"text/template", "net/textproto", "time",
		"crypto/tls", "go/token", "unicode", "unsafe",
		"net/url", "os/user", "unicode/utf16", "unicode/utf8",
		"crypto/x509", "encoding/xml", "archive/zip", "compress/zlib",
	}
	for _, pkg := range pkgs {
		builtinPkgs[pkg[strings.LastIndex(pkg, "/")+1:]] = pkg
	}
}
func Eval(code string) (out string, err string) {
	defer func() {  
		if e := recover(); e != nil {
			out = ""
			err = fmt.Sprintf("1:%v", e)
		}
	}()
	if ok, _ := regexp.MatchString("^ *package ", code); ok {
		out, err = run(code)
		return out, err
	}
	code = expandAliases(code)
	topLevel, nonTopLevel, pkgsToImport := partition(code)
	return buildAndExec(topLevel, nonTopLevel, pkgsToImport)
}
const (
	KSTRING = iota + 1
	KCOMMENT
	KTEXT
)
type Chunk struct {
	kind  int     
	text  string  
	numNL int     
}
type State struct {
	lineNum int
	pkgsToImport map[string]bool
	isTopLevel   bool
	brackOpenAt int
	brackCount int
	closingCh uint8
	chunks map[int][]Chunk
}
func partition(code string) (topLevel string, nonTopLevel string, pkgsToImport map[string]bool) {
	state := &State{
		lineNum:      1,
		pkgsToImport: make(map[string]bool),
		isTopLevel:   false,
		brackOpenAt:  0,
		closingCh:    ' ',
		brackCount:   0,
		chunks:       make(map[int][]Chunk),
	}
	topLevel = ""
	nonTopLevel = ""
	scanner := NewScanner(code)
	for {
		chunk, err := nextChunk(scanner)
		if err != nil {
			if err == io.EOF {
				break
			} else {
				panic(err)
			}
		}
		addChunk(state, chunk)
	}
	for lineNum := 1; lineNum <= state.lineNum; lineNum++ {
		line := processLine(lineNum, state)
		if state.isTopLevel {
			topLevel = addLine(lineNum, topLevel, line)
		} else {
			nonTopLevel = addLine(lineNum, nonTopLevel, line)
		}
	}
	if state.brackCount > 0 {
		panic(fmt.Sprintf("%d: Bracket or paren not closed. %d", state.brackOpenAt, state.brackCount))
	}
	return topLevel, nonTopLevel, state.pkgsToImport
}
func addLine(lineNum int, code string, line string) string {
	if len(code) == 0 || code[len(code)-1] == '\n' {
		return code + fmt.Sprintf("//line :%d\n", lineNum) + line
	} else {
		return code + line
	}
	return ""
}