Esempio n. 1
0
func WhatisCommand(args []string) {
	if len(args) == 2 {
		arg := args[1]
		if _, ok := repl.Env.Pkg(arg).(*eval.SimpleEnv); ok {
			repl.Msg("`%s' is a package", arg)
			return
		}
		ids := strings.Split(arg, ".")
		if len(ids) == 1 {
			name := ids[0]
			if typ := repl.Env.Type(name); typ != nil {
				repl.Msg("%s is a type: %s", typ.String())
				return
			}
		}
		if len(ids) == 2 {
			pkgName := ids[0]
			name := ids[1]
			if pkg, ok := repl.Env.Pkg(pkgName).(*eval.SimpleEnv); ok {
				if typ := pkg.Type(name); typ != nil {
					repl.Msg("%s is a kind: %s", arg, typ.Kind())
					repl.Msg("%s is a type: %v", arg, typ)
					return
				}
			}
		}
	}
	line := repl.CmdLine[len(args[0]):len(repl.CmdLine)]
	if expr, err := parser.ParseExpr(line); err != nil {
		if pair := eval.FormatErrorPos(line, err.Error()); len(pair) == 2 {
			repl.Msg(pair[0])
			repl.Msg(pair[1])
		}
		repl.Errmsg("parse error: %s\n", err)
	} else if cexpr, errs := eval.CheckExpr(expr, repl.Env); len(errs) != 0 {
		for _, cerr := range errs {
			repl.Msg("%v", cerr)
		}
	} else {
		repl.Section(cexpr.String())
		if cexpr.IsConst() {
			repl.Msg("constant:\t%s", cexpr.Const())
		}
		knownTypes := cexpr.KnownType()
		if len(knownTypes) == 1 {
			repl.Msg("type:\t%s", knownTypes[0])
		} else {
			for i, v := range knownTypes {
				repl.Msg("type[%d]:\t%s", i, v)
			}
		}
	}
}
Esempio n. 2
0
// REPL is the read, eval, and print loop.
func REPL(env *eval.SimpleEnv, readLineFn ReadLineFnType, inspectFn InspectFnType) {

	var err error

	// A place to store result values of expressions entered
	// interactively
	results := make([]interface{}, 0, 10)
	env.Vars["results"] = reflect.ValueOf(&results)

	Env = env
	exprs := 0
	line, err := readLineFn("gofish> ", true)
	for true {
		if err != nil {
			if err == io.EOF {
				break
			}
			panic(err)
		}
		if wasProcessed(line) {
			if LeaveREPL {
				break
			}
			line, err = readLineFn("gofish> ", true)
			continue
		}
		if stmt, err := eval.ParseStmt(line); err != nil {
			if pair := eval.FormatErrorPos(line, err.Error()); len(pair) == 2 {
				Msg(pair[0])
				Msg(pair[1])
			}
			Errmsg("parse error: %s", err)
		} else if expr, ok := stmt.(*ast.ExprStmt); ok {
			if cexpr, errs := eval.CheckExpr(expr.X, env); len(errs) != 0 {
				for _, cerr := range errs {
					Errmsg("%v", cerr)
				}
			} else if vals, err := eval.EvalExpr(cexpr, env); err != nil {
				Errmsg("panic: %s", err)
			} else if len(vals) == 0 {
				fmt.Printf("Kind=Slice\nvoid\n")
			} else if len(vals) == 1 {
				value := (vals)[0]
				if value.IsValid() {
					kind := value.Kind().String()
					typ := value.Type().String()
					if typ != kind {
						Msg("Kind = %v", kind)
						Msg("Type = %v", typ)
					} else {
						Msg("Kind = Type = %v", kind)
					}
					Msg("results[%d] = %s", exprs, inspectFn(value))
					exprs += 1
					results = append(results, (vals)[0].Interface())
				} else {
					Msg("%s", value)
				}
			} else {
				Msg("Kind = Multi-Value")
				size := len(vals)
				for i, v := range vals {
					fmt.Printf("%s", inspectFn(v))
					if i < size-1 {
						fmt.Printf(", ")
					}
				}
				Msg("")
				exprs += 1
				results = append(results, vals)
			}
		} else {
			if cstmt, errs := eval.CheckStmt(stmt, env); len(errs) != 0 {
				for _, cerr := range errs {
					Errmsg("%v", cerr)
				}
			} else if _, err := eval.InterpStmt(cstmt, env); err != nil {
				Errmsg("panic: %s", err)
			}
		}
		line, err = readLineFn("gofish> ", true)
	}
}