Exemple #1
0
func formtokNode(ns []parsec.ParsecNode) parsec.ParsecNode {
	switch n := ns[0].(type) {
	case *parsec.Terminal:
		switch n.Name {
		case "TERM":
			return termNode(n)
		case "REF":
			return refNode(n)
		case "FORMTOK":
			return common.NewForm(
				"##formtok",
				func(_ common.Scope, _ ...interface{}) interface{} {
					return n.Value
				})
		}

	case string:
		str := n[1 : len(n)-1]
		return common.NewForm(
			"##string",
			func(_ common.Scope, _ ...interface{}) interface{} { return str })

	case *common.Form:
		return n
	}
	panic(fmt.Errorf("unknown form type %T\n", ns[0]))
}
Exemple #2
0
func formNode(ns []parsec.ParsecNode) parsec.ParsecNode {
	name := ns[1].(*parsec.Terminal).Value
	ns = ns[2].([]parsec.ParsecNode)
	form, ok := builtins[name]
	if ok { // apply builtin form.
		return common.NewForm(
			name,
			func(scope common.Scope, _ ...interface{}) interface{} {
				args := make([]interface{}, 0, len(ns))
				for _, n := range ns {
					args = append(args, n.(*common.Form).Eval(scope))
				}
				return form.Eval(scope, args...)
			})
	}
	// apply non-terminal
	return common.NewForm(
		"#"+name,
		func(scope common.Scope, _ ...interface{}) interface{} {
			forms, ok := scope.GetNonTerminal(name)
			if ok {
				val := EvalForms(name, scope, forms)
				scope.Set(name, val, false /*global*/)
				return val
			}
			panic(fmt.Errorf("unknown form name %v\n", name))
		})
}
Exemple #3
0
func ruletokNode(ns []parsec.ParsecNode) parsec.ParsecNode {
	switch n := ns[0].(type) {
	case *parsec.Terminal:
		switch n.Name {
		case "IDENT":
			return identNode(n)
		case "TERM":
			return termNode(n)
		case "REF":
			return refNode(n)
		case "STRING":
			str := n.Value[1 : len(n.Value)-1]
			return common.NewForm(
				"##string",
				func(_ common.Scope, _ ...interface{}) interface{} { return str })
		default:
			panic(fmt.Errorf("unknown terminal name %v\n", n.Name))
		}

	case string:
		str := n[1 : len(n)-1]
		return common.NewForm(
			"##string",
			func(_ common.Scope, _ ...interface{}) interface{} { return str })

	case *common.Form:
		return n
	}
	panic(fmt.Errorf("unknown form type %T\n", ns[0]))
}
Exemple #4
0
func ruleNode(ns []parsec.ParsecNode) parsec.ParsecNode {
	// compute rule weight.
	var weight, restrain float64
	if len(ns) > 1 {
		if weigh := ns[0].(*common.Form); weigh.Name == "weigh" {
			rs := weigh.Eval(make(common.Scope)).([]interface{})
			weight, restrain = rs[0].(float64), rs[1].(float64)
			ns = ns[1:]
		}
	}
	// compose rule-form.
	rats := make([]*common.Form, 0, len(ns))
	for _, n := range ns {
		rats = append(rats, n.(*common.Form))
	}
	form := common.NewForm(
		"##rule",
		func(scope common.Scope, _ ...interface{}) interface{} {
			str := ""
			for i, rat := range rats {
				val := rat.Eval(scope)
				if val == nil {
					return nil
				}
				scope.Set("#"+strconv.Itoa(i), val, false /*global*/)
				str += fmt.Sprintf("%v", val)
			}
			return str
		})
	form.SetWeight(weight, restrain)
	return form
}
Exemple #5
0
func varNode(n *parsec.Terminal) *common.Form {
	return common.NewForm(
		"##var",
		func(scope common.Scope, _ ...interface{}) interface{} {
			val, _, ok := scope.Get(n.Value)
			if !ok {
				panic(fmt.Errorf("unknown variable %v\n", n.Value))
			}
			return val
		})
}
Exemple #6
0
func litNode(ns []parsec.ParsecNode) parsec.ParsecNode {
	if ns == nil || len(ns) == 0 {
		return nil
	}

	if s, ok := ns[0].(string); ok {
		return s
	}

	var val interface{}
	var err error
	t := ns[0].(*parsec.Terminal)
	switch t.Name {
	case "INT":
		val, err = strconv.ParseInt(t.Value, 10, 64)
		if err != nil {
			panic(fmt.Errorf("cannot parse %v for integer\n", t))
		}

	case "HEX":
		val, err = strconv.ParseInt(t.Value, 16, 64)
		if err != nil {
			panic(fmt.Errorf("cannot parse %v for hexadecimal\n", t))
		}

	case "OCT":
		val, err = strconv.ParseInt(t.Value, 8, 64)
		if err != nil {
			panic(fmt.Errorf("cannot parse %v for octal\n", t))
		}

	case "FLOAT":
		val, err = strconv.ParseFloat(t.Value, 64)
		if err != nil {
			panic(fmt.Errorf("cannot parse %v for float64\n", t))
		}

	case "STRING":
		val = t.Value[1 : len(t.Value)-1]

	case "TRUE":
		val = true

	case "FALSE":
		val = false
	}
	return common.NewForm(
		"##literaltok",
		func(_ common.Scope, _ ...interface{}) interface{} { return val })
}
Exemple #7
0
func identNode(n *parsec.Terminal) *common.Form {
	return common.NewForm(
		"##ident",
		func(scope common.Scope, _ ...interface{}) interface{} {
			name := n.Value
			forms, ok := scope.GetNonTerminal(name)
			if ok {
				val := EvalForms(name, scope, forms)
				scope.Set(n.Value, val, false /*global*/)
				return val
			}
			panic(fmt.Errorf("unknown nonterminal %v\n", n.Value))
		})
}
Exemple #8
0
func refNode(n *parsec.Terminal) *common.Form {
	return common.NewForm(
		"##ref",
		func(scope common.Scope, _ ...interface{}) interface{} {
			switch n.Value[0] {
			case '$':
				val, _, ok := scope.Get(n.Value[1:])
				if !ok {
					panic(fmt.Errorf("unknown reference %v\n", n.Value))
				}
				return val
			case '#':
				val, _, ok := scope.Get(n.Value)
				if !ok {
					panic(fmt.Errorf("unknown argument %v\n", n.Value))
				}
				return val
			}
			panic(fmt.Errorf("unknown form %v as part of rule\n", n.Value))
		})
}
Exemple #9
0
func initBuiltins() {
	builtins["let"] = common.NewForm("let", builtin.Let)
	builtins["letr"] = common.NewForm("letr", builtin.Letr)
	builtins["global"] = common.NewForm("global", builtin.Global)
	builtins["weigh"] = common.NewForm("weigh", builtin.Weigh)
	builtins["bag"] = common.NewForm("bag", builtin.Bag)
	builtins["range"] = common.NewForm("range", builtin.Range)
	builtins["rangef"] = common.NewForm("rangef", builtin.Rangef)
	builtins["ranget"] = common.NewForm("ranget", builtin.Ranget)
	builtins["choice"] = common.NewForm("choice", builtin.Choice)
	builtins["uuid"] = common.NewForm("uuid", builtin.Uuid)
	builtins["inc"] = common.NewForm("inc", builtin.Inc)
	builtins["dec"] = common.NewForm("dec", builtin.Dec)
	builtins["len"] = common.NewForm("len", builtin.Len)
	builtins["sprintf"] = common.NewForm("sprintf", builtin.Sprintf)
}
Exemple #10
0
func termNode(n *parsec.Terminal) *common.Form {
	str, _ := literals[n.Value]
	return common.NewForm(
		"##term",
		func(_ common.Scope, _ ...interface{}) interface{} { return str })
}