Exemplo n.º 1
0
// SourceText evaluates a chunk of elvish source.
func (ev *Evaler) SourceText(name, src, dir string) ([]Value, error) {
	n, err := parse.Parse(name, src)
	if err != nil {
		return nil, err
	}
	return ev.Eval(name, src, dir, n)
}
Exemplo n.º 2
0
func mustParse(name, text string) *parse.Chunk {
	n, e := parse.Parse(name, text)
	if e != nil {
		panic("parser error")
	}
	return n
}
Exemplo n.º 3
0
// UseForm = 'use' StringPrimary.modname Primary.fname
//         = 'use' StringPrimary.fname
func compileUse(cc *compileCtx, fn *parse.Form) exitusOp {
	var fnameNode *parse.Compound
	var fname, modname string

	switch len(fn.Args.Nodes) {
	case 0:
		cc.errorf(fn.Args.Pos, "expect module name or file name")
	case 1, 2:
		fnameNode = fn.Args.Nodes[0]
		_, fname = ensureStringPrimary(cc, fnameNode, "expect string literal")
		if len(fn.Args.Nodes) == 2 {
			modnameNode := fn.Args.Nodes[1]
			_, modname = ensureStringPrimary(
				cc, modnameNode, "expect string literal")
			if modname == "" {
				cc.errorf(modnameNode.Pos, "module name is empty")
			}
		} else {
			modname = stem(fname)
			if modname == "" {
				cc.errorf(fnameNode.Pos, "stem of file name is empty")
			}
		}
	default:
		cc.errorf(fn.Args.Nodes[2].Pos, "superfluous argument")
	}
	switch {
	case strings.HasPrefix(fname, "/"):
		// Absolute file name, do nothing
	case strings.HasPrefix(fname, "./") || strings.HasPrefix(fname, "../"):
		// File name relative to current source
		fname = path.Clean(path.Join(cc.dir, fname))
	default:
		// File name relative to data dir
		fname = path.Clean(path.Join(cc.dataDir, fname))
	}
	src, err := readFileUTF8(fname)
	if err != nil {
		cc.errorf(fnameNode.Pos, "cannot read module: %s", err.Error())
	}

	cn, err := parse.Parse(fname, src)
	if err != nil {
		// TODO(xiaq): Pretty print
		cc.errorf(fnameNode.Pos, "cannot parse module: %s", err.Error())
	}

	newCc := &compileCtx{
		cc.Compiler,
		fname, src, path.Dir(fname),
		[]staticNS{staticNS{}}, staticNS{},
	}

	op, err := newCc.compile(cn)
	if err != nil {
		// TODO(xiaq): Pretty print
		cc.errorf(fnameNode.Pos, "cannot compile module: %s", err.Error())
	}

	cc.mod[modname] = newCc.scopes[0]

	return func(ec *evalCtx) exitus {
		// TODO(xiaq): Should handle failures when evaluting the module
		newEc := &evalCtx{
			ec.Evaler,
			fname, src, "module " + modname,
			ns{}, ns{},
			ec.ports,
		}
		op.f(newEc)
		ec.mod[modname] = newEc.local
		return ok
	}
}
Exemplo n.º 4
0
// TODO(xiaq): Currently only the editor deals with signals.
func interact() {
	ev, st := newEvalerAndStore()
	datadir, err := store.EnsureDataDir()
	printError(err)
	if err == nil {
		// XXX
		vs, err := ev.Source(datadir + "/rc.elv")
		if err != nil && !os.IsNotExist(err) {
			printError(err)
		}
		eval.PrintExituses(vs)
	}

	cmdNum := 0

	username := "******"
	user, err := user.Current()
	if err == nil {
		username = user.Username
	}
	hostname, err := os.Hostname()
	if err != nil {
		hostname = "???"
	}
	rpromptStr := username + "@" + hostname

	sigch := make(chan os.Signal, sigchSize)
	signal.Notify(sigch)
	defer signal.Stop(sigch)

	ed := edit.NewEditor(os.Stdin, sigch, st)

	for {
		cmdNum++
		name := fmt.Sprintf("<tty %d>", cmdNum)

		prompt := func() string {
			return sysutil.Getwd() + "> "
		}
		rprompt := func() string {
			return rpromptStr
		}

		lr := ed.ReadLine(prompt, rprompt)

		if lr.EOF {
			break
		} else if lr.Err != nil {
			fmt.Println("Editor error:", lr.Err)
			fmt.Println("My pid is", os.Getpid())
		}

		n, err := parse.Parse(name, lr.Line)
		printError(err)

		if err == nil {
			vs, err := ev.Eval(name, lr.Line, ".", n)
			printError(err)
			eval.PrintExituses(vs)
		}
	}
}