func stdUnit(f ir.ForeignType, ld Loader) *Unit { fake := ir.NewUnit(f.Name()) fake.Variables = f.Variables() fake.Infix = f.Infix() switch f.Name() { case "RND": fake.Rules["res"] = &stdRnd{} case "LD": assert.For(ld != nil, 20) fake.Rules["res"] = &stdLd{} case "LEAF": assert.For(ld != nil, 20) fake.Rules["out"] = &stdLeaf{} default: halt.As(100, "unknown standard unit ", f.Name()) } return &Unit{code: fake, loader: ld} }
func (t *target) init(mod string) { t.name = mod t.unit = ir.NewUnit(mod) t.cache = make(map[string]ir.ForeignType) }
func (i *intern) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) { var consumer func(interface{}) switch start.Name.Local { case "unit": u := ir.NewUnit(i.attr(&start, "name").(string)) i.x = u i.root = u consumer = func(_x interface{}) { switch x := _x.(type) { case *ir.Variable: u.Variables[x.Name] = x x.Unit = u case *ir.Const: u.Const[x.Name] = x case []string: for _, s := range x { u.Infix = append(u.Infix, u.Variables[s]) } case *pre: u.Pre = append(u.Pre, x) case *post: u.Post = append(u.Post, x) default: halt.As(100, reflect.TypeOf(x)) } } case "definition": f := &futureForeignType{} f.name = i.attr(&start, "name").(string) i.x = f f.fakeUnit = ir.NewUnit(f.name) i.root = f.fakeUnit consumer = func(_x interface{}) { switch x := _x.(type) { case *ir.Variable: f.fakeUnit.Variables[x.Name] = x x.Unit = f.fakeUnit case string: f.imps = append(f.imps, x) case []string: for _, s := range x { f.fakeUnit.Infix = append(f.fakeUnit.Infix, f.fakeUnit.Variables[s]) } default: halt.As(100, reflect.TypeOf(x)) } } case "in", "var", "reg", "out": v := &ir.Variable{} v.Name = i.attr(&start, "name").(string) switch start.Name.Local { case "in": v.Modifier = mods.IN case "var": v.Modifier = mods.NONE case "reg": v.Modifier = mods.REG case "out": v.Modifier = mods.OUT default: halt.As(100, start.Name.Local) } v.Type.Basic = i.attr(&start, "builtin").(bool) i.x = v i.consume(v) if v.Type.Basic { v.Type.Builtin = &ir.BuiltinType{} v.Type.Builtin.Code = types.TypMap[i.attr(&start, "type").(string)] consumer = func(_x interface{}) { switch x := _x.(type) { case ir.Rule: v.Unit.Rules[v.Name] = x default: halt.As(100, reflect.TypeOf(x)) } } } else { ff := &futureForeignType{} ff.name = i.attr(&start, "type").(string) ff.fakeUnit = ir.NewUnit(ff.name) v.Type.Foreign = ff rr := make(map[string]ir.Rule) v.Unit.ForeignRules[v.Name] = rr consumer = func(_x interface{}) { switch x := _x.(type) { case map[string]ir.Rule: for k, v := range x { rr[k] = v } default: halt.As(100, reflect.TypeOf(x)) } } } case "foreign": //wrapper for local rules of foreign objects id := i.attr(&start, "id").(string) consumer = func(_x interface{}) { switch x := _x.(type) { case ir.Rule: fn := make(map[string]ir.Rule) fn[id] = x i.consume(fn) default: halt.As(100, reflect.TypeOf(x)) } } case "import": name := i.attr(&start, "name").(string) i.consume(name) case "precondition": p := &pre{} i.x = p i.consume(p) consumer = func(_x interface{}) { switch x := _x.(type) { case ir.Expression: p.expr = x default: halt.As(100, reflect.TypeOf(x)) } } case "postcondition": p := &post{} i.x = p i.consume(p) consumer = func(_x interface{}) { switch x := _x.(type) { case ir.Expression: p.expr = x default: halt.As(100, reflect.TypeOf(x)) } } case "key": p := &key{} i.x = p i.consume(p) consumer = func(_x interface{}) { switch x := _x.(type) { case ir.Expression: p.expr = x default: halt.As(100, reflect.TypeOf(x)) } } case "value": p := &val{} i.x = p i.consume(p) consumer = func(_x interface{}) { switch x := _x.(type) { case ir.Expression: p.expr = x default: halt.As(100, reflect.TypeOf(x)) } } case "infix": if num, err := strconv.Atoi(i.attr(&start, "num").(string)); err == nil { var ret []string for j := 0; j < num; j++ { ret = append(ret, i.attr(&start, "arg"+strconv.Itoa(j)).(string)) } i.consume(ret) } else { halt.As(101, start) } case "becomes": r := &ir.AssignRule{} i.x = r i.consume(r) consumer = func(_x interface{}) { switch x := _x.(type) { case ir.Expression: r.Expr = x default: halt.As(100, reflect.TypeOf(x)) } } case "constant": c := &ir.Const{} c.Name = i.attr(&start, "name").(string) i.x = c i.consume(c) consumer = func(_x interface{}) { switch x := _x.(type) { case ir.Expression: c.Expr = x default: halt.As(100, reflect.TypeOf(x)) } } case "atom-expression": a := &ir.AtomExpr{} a.Value = i.attr(&start, "value").(string) i.x = a i.consume(a) case "constant-expression": c := &ir.ConstExpr{} c.Type = types.TypMap[i.attr(&start, "type").(string)] sd, _ := d.Token() if td, ok := sd.(xml.CharData); ok { c.Value = i.data(c.Type, td) } else { halt.As(100) } i.consume(c) i.x = c case "selector-expression": c := &ir.SelectExpr{} if un := i.attr(&start, "unit").(string); un == i.root.Name { if vn := i.attr(&start, "variable"); vn != nil { c.Var = &ir.Variable{Name: vn.(string)} if foreign, ok := i.attr(&start, "foreign").(string); ok { c.Foreign = &ir.Variable{Name: foreign} } } else if cn := i.attr(&start, "constant"); cn != nil { c.Const = &ir.Const{Name: cn.(string)} } else { halt.As(100) } c.Inner = mods.ModMap[i.attr(&start, "inner").(string)] consumer = func(_x interface{}) { switch x := _x.(type) { case ir.Expression: c.ExprList = append(c.ExprList, x) default: halt.As(100, reflect.TypeOf(x)) } } } else { halt.As(100, un) } i.x = c i.consume(c) case "monadic-expression": m := &ir.Monadic{} op := i.attr(&start, "op").(string) m.Op = ops.OpMap[op] i.x = m i.consume(m) consumer = func(_x interface{}) { switch x := _x.(type) { case ir.Expression: m.Expr = x default: halt.As(100, reflect.TypeOf(x)) } } case "type-test-expression": t := &ir.TypeTest{} typ := i.attr(&start, "type").(string) t.Typ.Basic = true t.Typ.Builtin = &ir.BuiltinType{Code: types.TypMap[typ]} i.x = t i.consume(t) consumer = func(_x interface{}) { switch x := _x.(type) { case ir.Expression: t.Operand = x default: halt.As(100, reflect.TypeOf(x)) } } case "dyadic-expression": c := &ir.Dyadic{} op := i.attr(&start, "op").(string) c.Op = ops.OpMap[op] i.x = c i.consume(c) consumer = func(_x interface{}) { switch x := _x.(type) { case ir.Expression: if c.Left == nil { c.Left = x } else { c.Right = x } default: halt.As(100, reflect.TypeOf(x)) } } case "ternary-expression": t := &ir.Ternary{} i.x = t i.consume(t) consumer = func(_x interface{}) { switch x := _x.(type) { case ir.Expression: if t.If == nil { t.If = x } else if t.Then == nil { t.Then = x } else if t.Else == nil { t.Else = x } else { halt.As(100, "too much") } default: halt.As(100, reflect.TypeOf(x)) } } case "infix-expression": inf := &ir.InfixExpr{} inf.Unit = &futureForeignType{name: i.attr(&start, "unit").(string)} i.x = inf i.consume(inf) consumer = func(_x interface{}) { switch x := _x.(type) { case ir.Expression: inf.Args = append(inf.Args, x) default: halt.As(100, reflect.TypeOf(x)) } } case "list-expression": l := &ir.ListExpr{} i.x = l i.consume(l) consumer = func(_x interface{}) { switch x := _x.(type) { case ir.Expression: l.Expr = append(l.Expr, x) default: halt.As(100, reflect.TypeOf(x)) } } case "set-expression": l := &ir.SetExpr{} i.x = l i.consume(l) consumer = func(_x interface{}) { switch x := _x.(type) { case ir.Expression: l.Expr = append(l.Expr, x) default: halt.As(100, reflect.TypeOf(x)) } } case "map-expression": l := &ir.MapExpr{} i.x = l i.consume(l) consumer = func(_x interface{}) { switch x := _x.(type) { case *key: l.Key = append(l.Key, x) case *val: l.Value = append(l.Value, x) default: halt.As(100, reflect.TypeOf(x)) } } default: halt.As(100, start.Name.Local) } var _t xml.Token for stop := false; !stop && err == nil; { _t, err = d.Token() switch t := _t.(type) { case xml.StartElement: x := &intern{root: i.root} x.consume = consumer d.DecodeElement(x, &t) case xml.EndElement: stop = t.Name == start.Name default: halt.As(100, reflect.TypeOf(t), t) } } return }