Пример #1
0
func Execute(command string) {
	output := dsl.Query(command)
	valuestring := dsl.Query("echo $?")
	value, _ := strconv.Atoi(valuestring[0 : len(valuestring)-2])
	if value != 0 {
		panic(fmt.Sprintf("executing `%s` failed: %s", command, output))
	}
}
Пример #2
0
func interpret(n *Node, s *scope) (string, interrupt) {
	i := interrupt{}
	switch n.typ {
	case "lesson":
		_, i = interpret(n.children[0], s)
		if i.typ != "" {
			return "", i
		}
		return "", interrupt{"done", ""}
	case "block":
		var v string
		for _, node := range n.children {
			v, i = interpret(node, s)
			if i.typ != "" {
				return "", i
			}
		}
		return v, i
	case "prompt":
		block := n.children[0]
		expects := node("expects")
		if len(n.children) > 1 {
			expects = n.children[1]
		}
		for {
			if s.test {
				if len(expects.children) > 0 {
					// by default, take the first one
					s.current_expect = expects.children[0].children[1].children[0].children[0].typ
					var interaction string
					if len(expects.children[0].children[1].children) > 1 {
						interaction = expects.children[0].children[1].children[1].children[0].typ
					}
					// but we prefer any unchecked ones
					for _, e := range expects.children {
						if e.children[2].children[0].typ == "false" {
							s.current_expect = e.children[1].children[0].children[0].typ
						}
					}
					ok := dsl.SimulatePrompt(s.current_expect, interaction)
					if !ok {
						return "", interrupt{"lesson", ""}
					}
					goto skip
				} else {
					dsl.Say("[No expect, falling back to manual mode.")
				}
			}

			if !dsl.Prompt() {
				// cli terminated
				return "", interrupt{"lesson", ""}
			}
		skip:

			for _, block := range s.blocks {
				_, i := interpret(block, s)
				if i.typ != "" {
					return "", i
				}
			}
			_, i := interpret(block, s)
			if i.typ == "break" {
				break
			}
			if i.typ != "" {
				return "", i
			}
			if s.test {
				if s.current_expect != "" {
					panic("Expect was not reached: " + s.current_expect)
				}
			}
		}
		// TODO: return?
	case "if":
		condition := n.children[0]
		block := n.children[1]
		else_block := n.children[2]
		v, i := interpret(condition, s)
		if i.typ != "" {
			return "", i
		}
		if v == "" {
			v, i = interpret(else_block, s)
		} else {
			v, i = interpret(block, s)
		}
		if i.typ != "" {
			return "", i
		}
		return v, i
	case "state":
		promptblock := n.children[0]
		s.blocks = append(s.blocks, promptblock)
		block := n.children[1]
		_, i := interpret(block, s)
		if i.typ != "" {
			return "", i
		}
	case "def":
		name := n.children[0].typ
		s.defs[name] = n
	case "call":
		method := n.children[0].typ
		arguments := n.children[1]
		evaluated_arguments := make([]string, 0)
		for _, arg := range arguments.children {
			v, i := interpret(arg, s)
			if i.typ != "" {
				return "", i
			}
			evaluated_arguments = append(evaluated_arguments, v)
		}

		switch method {
		case "say":
			dsl.Say(evaluated_arguments[0])
		case "command":
			return dsl.LastCommand(), i
		case "output":
			return dsl.LastOutput(), i
		case "match":
			if regexp.MustCompile(evaluated_arguments[1]).MatchString(evaluated_arguments[0]) {
				return "true", i
			} else {
				return "", i
			}
		case "equal":
			if evaluated_arguments[0] == evaluated_arguments[1] {
				return "true", i
			} else {
				return "", i
			}
		case "run":
			s, ok := dsl.Query(evaluated_arguments[0])
			if !ok {
				return "", interrupt{"lesson", ""}
			}
			return s, i
		case "break":
			return "", interrupt{"break", ""}
		case "lesson":
			return "", interrupt{"lesson", evaluated_arguments[0]}
		case "done":
			return "", interrupt{"done", ""}
		case "return":
			return evaluated_arguments[0], i
		case "expect":
			if evaluated_arguments[0] == s.current_expect {
				s.current_expect = ""
				n.children[2].children[0].typ = "true"
			}
			return "", i
		case "lesson_name":
			return "", i
		default:
			def, ok := s.defs[method]
			if ok {
				for i, arg := range def.children[1].children {
					name := arg.children[0].typ
					s.defs[name] = node("def", node(name), node("arguments"), node("block", node("call", node("return"), node("stringexpressions", node("string", node(evaluated_arguments[i]))))))

				}
				block := def.children[2]
				v, i := interpret(block, s)
				if i.typ != "" {
					return "", i
				}
				return v, i
			} else {
				panic("Cannot find method '" + method + "'.")
			}
		}
	case "+":
		v1, i := interpret(n.children[0], s)
		if i.typ != "" {
			return "", i
		}
		v2, i := interpret(n.children[1], s)
		if i.typ != "" {
			return "", i
		}
		return v1 + v2, i
	case "string":
		return n.children[0].typ, i
	case "and":
		v1, i := interpret(n.children[0], s)
		if i.typ != "" {
			return "", i
		}
		v2, i := interpret(n.children[1], s)
		if i.typ != "" {
			return "", i
		}
		return bool2str(str2bool(v1) && str2bool(v2)), i
	case "or":
		v1, i := interpret(n.children[0], s)
		if i.typ != "" {
			return "", i
		}
		v2, i := interpret(n.children[1], s)
		if i.typ != "" {
			return "", i
		}
		return bool2str(str2bool(v1) || str2bool(v2)), i
	case "not":
		v, i := interpret(n.children[0], s)
		if i.typ != "" {
			return "", i
		}
		return bool2str(!str2bool(v)), i
	default:
		panic("I don't know how to interpret a '" + n.typ + "' node.")
	}
	return "whatever", i
}
Пример #3
0
func QueryReturn(query string) int {
	dsl.Query(query)
	output := dsl.Query("echo $?")
	value, _ := strconv.Atoi(output[0 : len(output)-2])
	return value
}