func conv(v *value, target types.Type) (ret *value) { switch { case v.typ == types.ANY && target == types.UNIT: a := v.toAny() assert.For(a.x == nil, 20) ret = &value{typ: types.UNIT, val: &Ref{}} case v.typ == types.INTEGER && target == types.REAL: i := v.toInt() x := big.NewRat(0, 1) ret = &value{typ: target, val: ThisRat(x.SetInt(i))} case v.typ == types.BOOLEAN && target == types.TRILEAN: b := v.toBool() x := tri.This(b) ret = &value{typ: target, val: x} case v.typ == types.ANY && target == types.ATOM: ret = &value{typ: target, val: Atom("")} case target == types.ANY && v.typ != types.ANY: x := ThisAny(v) ret = &value{typ: target, val: x} case target == types.ANY && v.typ == types.ANY: x := v.toAny() ret = &value{typ: target, val: x} case v.typ == target: ret = v } assert.For(ret != nil, 60, v.typ, target, v.val) return }
/* func dyPTR() { putDyadic(types.PTR, types.PTR, ops.Eq, b_(b_ptr_(b_ptr_ptr_(func(lp *Ptr, rp *Ptr) bool { return lp.adr == rp.adr })))) putDyadic(types.PTR, types.PTR, ops.Neq, b_(b_ptr_(b_ptr_ptr_(func(lp *Ptr, rp *Ptr) bool { return lp.adr != rp.adr })))) } */ func dyPROC() { putDyadic(types.UNIT, types.UNIT, ops.Eq, b_(b_proc_(b_proc_proc_(func(lp *Ref, rp *Ref) bool { return lp.u == rp.u })))) putDyadic(types.UNIT, types.UNIT, ops.Neq, b_(b_proc_(b_proc_proc_(func(lp *Ref, rp *Ref) bool { return lp.u != rp.u })))) putDyadic(types.UNIT, types.ANY, ops.Eq, b_(b_proc_(b_proc_z_(func(la *Ref, ra *Any) bool { assert.For(ra.x == nil, 40, "UNDEF comparision only") return la.u == nil })))) putDyadic(types.ANY, types.UNIT, ops.Eq, b_(b_z_(b_z_proc_(func(la *Any, ra *Ref) bool { assert.For(la.x == nil, 40, "UNDEF comparision only") return ra.u == nil })))) putDyadic(types.UNIT, types.ANY, ops.Neq, b_(b_proc_(b_proc_z_(func(la *Ref, ra *Any) bool { assert.For(ra.x == nil, 40, "UNDEF comparision only") return la.u != nil })))) putDyadic(types.ANY, types.UNIT, ops.Neq, b_(b_z_(b_z_proc_(func(la *Any, ra *Ref) bool { assert.For(la.x == nil, 40, "UNDEF comparision only") return ra.u != nil })))) }
func (i *intern) data(t types.Type, cd xml.CharData) (ret interface{}) { switch t { case types.INTEGER, types.REAL: ret = string(cd) case types.BOOLEAN: ret = string(cd) == "true" case types.TRILEAN: if s := string(cd); s == "null" { ret = tri.NIL } else if s == "true" { ret = tri.TRUE } else { ret = tri.FALSE } case types.CHAR: c, _ := strconv.ParseUint(string(cd), 16, 64) ret = rune(c) case types.STRING: data, err := base64.StdEncoding.DecodeString(string(cd)) assert.For(err == nil, 30) ret = strings.TrimPrefix(string(data), prefix) case types.ANY: assert.For(string(cd) == "null", 20) ret = nil default: halt.As(100, t) } return }
func (p *pr) rulesDecl() { assert.For(p.sym.Code == lss.Process, 20, "PROCESS block expected") p.next() for stop := false; !stop; { p.pass(lss.Delimiter, lss.Separator) expr := &exprBuilder{tgt: &p.target, marker: p} p.expression(expr) p.expect(lss.ArrowRight, "assign expected", lss.Delimiter, lss.Separator) p.next() p.pass(lss.Delimiter, lss.Separator) id := p.ident() var fid string p.next() if p.is(lss.Period) { u := p.target.unit.Variables[id] if u.Type.Basic { p.mark("only foreign types are selectable") } p.next() p.expect(lss.Ident, "foreign variable expected") fid = p.ident() p.next() } else { fid = id id = p.target.unit.Name } assert.For(fid != "", 40) p.target.assign(id, fid, expr) p.pass(lss.Separator, lss.Delimiter) stop = p.is(lss.End) } }
func Construct(name otm.Qualident) (ret schema.Guide) { assert.For(name.Template == "ng", 20, name) fn := Constructors[name.Class] assert.For(fn != nil, 40, name) ret = fn() assert.For(ret != nil, 60, name) return }
func (l *futureLink) Object() otm.Object { if l.o == nil { assert.For(!fn.IsNil(l.up), 20) l.o = otm.RootOf(l.up).FindById(l.to).(*object) assert.For(l.o != nil, 60, "object not found ", l.to) } return l.o }
func dyINT2REAL() { putDyadic(types.REAL, types.INTEGER, ops.Quot, r_(r_ir_(r_ir_ir_(func(l *big.Rat, r *big.Rat) *big.Rat { return l.Quo(l, r) })))) putDyadic(types.INTEGER, types.REAL, ops.Quot, r_(r_ir_(r_ir_ir_(func(l *big.Rat, r *big.Rat) *big.Rat { return l.Quo(l, r) })))) putDyadic(types.REAL, types.INTEGER, ops.Pow, r_(r_ir_(r_ir_ir_(func(l *big.Rat, r *big.Rat) *big.Rat { n := l.Num() d := l.Denom() assert.For(r.IsInt(), 40) p := r.Num() assert.For(p.Cmp(big.NewInt(0)) >= 0, 40, "positive only") n = n.Exp(n, p, nil) d = d.Exp(d, p, nil) ret := big.NewRat(0, 1) ret = ret.SetFrac(n, d) return ret })))) putDyadic(types.INTEGER, types.REAL, ops.Pow, r_(r_ir_(r_ir_ir_(func(l *big.Rat, r *big.Rat) *big.Rat { assert.For(l.IsInt(), 40) n := l.Num() p := r.Num() q := r.Denom() assert.For(p.Cmp(big.NewInt(0)) >= 0, 40, "positive only") assert.For(q.Cmp(big.NewInt(1)) == 0, 41, "извлечение корня не поддерживается") n = n.Exp(n, p, q) ret := big.NewRat(0, 1) ret = ret.SetFrac(n, big.NewInt(1)) return ret })))) putDyadic(types.INTEGER, types.REAL, ops.Prod, r_(r_ir_(r_ir_ir_(func(l *big.Rat, r *big.Rat) *big.Rat { return l.Mul(l, r) })))) putDyadic(types.REAL, types.INTEGER, ops.Prod, r_(r_ir_(r_ir_ir_(func(l *big.Rat, r *big.Rat) *big.Rat { return l.Mul(l, r) })))) putDyadic(types.REAL, types.INTEGER, ops.Sum, r_(r_ir_(r_ir_ir_(func(l *big.Rat, r *big.Rat) *big.Rat { return l.Add(l, r) })))) putDyadic(types.REAL, types.INTEGER, ops.Diff, r_(r_ir_(r_ir_ir_(func(l *big.Rat, r *big.Rat) *big.Rat { return l.Sub(l, r) })))) putDyadic(types.INTEGER, types.INTEGER, ops.Quot, r_(r_ir_(r_ir_ir_(func(l *big.Rat, r *big.Rat) *big.Rat { return l.Quo(l, r) })))) }
func TestSome(t *testing.T) { assert.For(Do2(Do2(Int(4), SUM, Int(24)), EQ, Int(4+24)).ToBool(), 20) assert.For(Do2(Do2(Int(4), DIFF, Int(24)), EQ, Int(4-24)).ToBool(), 20) assert.For(Do2(Do2(Int(4), MULT, Int(24)), EQ, Int(4*24)).ToBool(), 20) t.Log(Do2(Int(4), QUOT, Int(24))) t.Log(Do(NEG, Int(45))) t.Log(Flo(34.5)) t.Log(Cpx(complex(3, 5))) t.Log(Do(CON, Cpx(complex(3.5, 14)))) }
func (b *builder) Child(prod otm.Producer, mod ...otm.Modifier) otm.Builder { assert.For(b.root != nil, 20) n := prod(mod...).(*object) if n.id != "" { old := b.root.FindById(n.id) assert.For(fn.IsNil(old), 40, "non unique id") } b.root.vl = append(b.root.vl, n) n.up = b.root return b }
//expect is the most powerful step forward runner, breaks the compilation if unexpected sym found func (p *common) expect(sym lss.Symbol, msg string, skip ...lss.Symbol) { assert.For(p.done, 20) if !p.await(sym, skip...) { p.mark(msg) } p.done = false }
func (s *sc) comment() { assert.For(s.ch == '*', 20, "expected ", s.opts.CommentTriplet[1], "got ", Token(s.ch)) for { for s.err == nil && s.ch != s.opts.CommentTriplet[1] { if s.ch == s.opts.CommentTriplet[0] { if s.next() == s.opts.CommentTriplet[1] { s.comment() } } else { s.next() } } for s.err == nil && s.ch == s.opts.CommentTriplet[1] { s.next() } if s.err != nil || s.ch == s.opts.CommentTriplet[2] { break } } if s.err == nil { s.next() } else { s.mark("unclosed comment") } }
func (t *target) emit(_s ir.Statement) { assert.For(!fn.IsNil(_s), 20) switch s := _s.(type) { default: t.tpl.Stmt = append(t.tpl.Stmt, s) } }
//expect is the most powerful step forward runner, breaks the compilation if unexpected sym found func (p *common) expect(sym ots.SymCode, msg string, skip ...ots.SymCode) { assert.For(p.done, 20) if !p.await(sym, skip...) { p.mark(msg) } p.done = false }
func Join(in *model.Layer, out *model.Layer) { j := 0 type im map[int]interface{} cache := make([]im, len(out.Nodes)) for k, n := range in.Nodes { for i := 0; i < len(n.Out); { assert.For(len(n.Out) <= len(out.Nodes), 20, len(n.Out), len(out.Nodes)) l := model.Link{NodeId: k, LinkId: i} skip := false if cache[j] != nil { if _, ok := cache[j][k]; ok { skip = true j++ if j == len(cache) { j = 0 } } } if !skip { out.Nodes[j].In[l] = nil if cache[j] == nil { cache[j] = make(im) } cache[j][k] = l //log.Println(l, "to", j) i++ } //log.Println(k, len(n.Out), i, j) } } in.Next = out }
//expect is the most powerful step forward runner, breaks the compilation if unexpected sym found func (r *rn) Expect(sym SymCode, msg interface{}, skip ...SymCode) { assert.For(r.done, 20, "previous symbol unhandled") if !r.Await(sym, skip...) { r.marker.Mark(msg) } r.done = false }
func (s *sc) comment() { assert.For(s.ch == '*', 20, "expected * ", "got ", Token(s.ch)) for { for s.err == nil && s.ch != '*' { if s.ch == '(' { if s.next() == '*' { s.comment() } } else { s.next() } } for s.err == nil && s.ch == '*' { s.next() } if s.err != nil || s.ch == ')' { break } } if s.err == nil { s.next() } else { s.mark("unclosed comment") } }
//first char always 0..9 func (s *sc) num() (sym Sym) { assert.For(unicode.IsDigit(s.ch), 20, "digit expected") var buf []rune var mbuf []rune hasDot := false for { buf = append(buf, s.ch) s.next() if s.ch == '.' { if !hasDot { hasDot = true } else if hasDot { s.mark("dot unexpected") } } if s.err != nil || !(s.ch == '.' || s.is(hex, s.ch)) { break } } if s.is(modifier, s.ch) { mbuf = append(mbuf, s.ch) s.next() } if s.err == nil { sym.Code = Number sym.Str = string(buf) sym.NumberOpts.Modifier = string(mbuf) sym.NumberOpts.Period = hasDot } else { s.mark("error reading number") } return }
func Init(_top string, ld Loader) (ret map[string]*Unit) { assert.For(ld != nil, 20, _top) ret = make(map[string]*Unit) var run func(*Unit) run = func(u *Unit) { u.imps = ret for _, v := range u.code.Variables { if !v.Type.Basic { if dep := ld(v.Type.Foreign.Name()); dep != nil { ret[imp(v)] = &Unit{code: dep, loader: ld} v.Type.Foreign = ir.NewForeign(dep) run(ret[imp(v)]) } } } } if std := lpp.Std[_top]; std != nil { ret[_top] = stdUnit(std, ld) run(ret[_top]) } else if top := ld(_top); top != nil { ret[_top] = &Unit{code: top, loader: ld} run(ret[_top]) } return }
func (s *sc) ident() (sym Sym) { assert.For(unicode.IsLetter(s.ch), 20, "character expected") var buf []rune for { buf = append(buf, s.ch) s.next() if s.err != nil || !(unicode.IsLetter(s.ch) || unicode.IsDigit(s.ch)) { break } } if s.err == nil { sym.Str = string(buf) key := sym.Str if s.evil == nil { x := true s.evil = &x if keyTab[key] == None && keyTab[strings.ToUpper(key)] == s.useTab[0] { *s.evil = true } else if keyTab[key] == s.useTab[0] { *s.evil = false } } set := func() { if sym.Code = keyTab[key]; sym.Code == None { sym.Code = Ident sym.User = s.foreignTab[key] } else if sym.Code != None { ok := false for _, u := range s.useTab { if u == sym.Code { ok = true break } } if !ok { sym.Code = Ident sym.User = s.foreignTab[key] } } } if s.evil != nil { if *s.evil { key = strings.ToUpper(sym.Str) if key != sym.Str { set() } else { sym.Code = Ident } } else { set() } } else { sym.Code = Ident } } else { s.mark("error while ident read") } return }
func (u *extern) attr(start *xml.StartElement, name string, value interface{}) { str := func(value string) { assert.For(value != "", 20) a := xml.Attr{} a.Name.Local = name a.Value = value start.Attr = append(start.Attr, a) } switch v := value.(type) { case string: str(v) case bool: if v { str("true") } else { str("false") } case int: str(strconv.Itoa(v)) case types.Type: str(v.String()) default: halt.As(100, reflect.TypeOf(v), v) } }
func (p *pr) varDecl() { assert.For(p.sym.Code == lss.Var || p.sym.Code == lss.Reg, 20, "VAR block expected") mod := mods.NONE if p.is(lss.Reg) { mod = mods.REG } p.next() for { if p.await(lss.Ident, lss.Delimiter, lss.Separator) { var vl []*ir.Variable for { id := p.ident() v := &ir.Variable{Name: id, Unit: p.target.unit} vl = append(vl, v) p.next() if mod == mods.NONE && p.await(lss.Minus) || p.is(lss.Plus) { v.Modifier = mods.SymMod[p.sym.Code] p.next() } else if mod != mods.NONE && p.is(lss.Minus) || p.is(lss.Plus) { p.mark("registers private only") } else if mod == mods.REG { v.Modifier = mods.REG } if p.await(lss.Comma, lss.Separator) { p.next() p.pass(lss.Separator) } else { break } } if p.await(lss.Ident, lss.Separator) { tb := &ir.Type{} p.typ(p.resolve, tb) for _, v := range vl { v.Type = *tb if !tb.Basic { p.target.foreign(v.Name, v) } if !tb.Basic && v.Modifier != mods.NONE { p.mark("only hidden foreigns allowed") } p.target.obj(v.Name, v) } } else if p.is(lss.Unit) { p.next() tb := ir.Type{} tb.Basic = true tb.Builtin = &ir.BuiltinType{Code: types.UNIT} for _, v := range vl { v.Type = tb p.target.obj(v.Name, v) } } else { p.mark("type or identifier expected") } } else { break } } }
func (p *common) number() (t types.Type, v interface{}) { assert.For(p.is(ots.Number), 20, "number expected here") switch p.sym.NumberOpts.Modifier { case "": if p.sym.NumberOpts.Period { t, v = types.REAL, p.sym.Value } else { //x, err := strconv.Atoi(p.sym.Str) //assert.For(err == nil, 40) t, v = types.INTEGER, p.sym.Value } case "U": if p.sym.NumberOpts.Period { p.mark("hex integer value expected") } //fmt.Println(p.sym) if r, err := strconv.ParseUint(p.sym.Value, 16, 64); err == nil { t = types.CHAR v = rune(r) } else { p.mark("error while reading integer") } case "H": if p.sym.NumberOpts.Period { p.mark("hex integer value expected") } t, v = types.INTEGER, p.sym.Value default: p.mark("unknown number format `", p.sym.NumberOpts.Modifier, "`") } return }
func (r *rn) Assert(sym SymCode, msg interface{}, skip ...SymCode) (ret Symbol) { assert.For(r.done, 20, "previous symbol unhandled") r.Expect(sym, msg, skip...) ret = r.Sym() r.Next() return }
func dyINTEGER() { putDyadic(types.INTEGER, types.INTEGER, ops.Sum, i_(i_i_(i_i_i_(func(l *big.Int, r *big.Int) *big.Int { return l.Add(l, r) })))) putDyadic(types.INTEGER, types.INTEGER, ops.Diff, i_(i_i_(i_i_i_(func(l *big.Int, r *big.Int) *big.Int { return l.Sub(l, r) })))) putDyadic(types.INTEGER, types.INTEGER, ops.Prod, i_(i_i_(i_i_i_(func(l *big.Int, r *big.Int) *big.Int { return l.Mul(l, r) })))) putDyadic(types.INTEGER, types.INTEGER, ops.Div, i_(i_i_(i_i_i_(func(l *big.Int, r *big.Int) *big.Int { return l.Div(l, r) })))) putDyadic(types.INTEGER, types.INTEGER, ops.Mod, i_(i_i_(i_i_i_(func(l *big.Int, r *big.Int) *big.Int { return l.Mod(l, r) })))) putDyadic(types.INTEGER, types.INTEGER, ops.Pow, i_(i_i_(i_i_i_(func(l *big.Int, r *big.Int) *big.Int { fmt.Println("to do full functional power") assert.For(r.Cmp(big.NewInt(0)) >= eq, 40, "nonnegative only", r) return l.Exp(l, r, big.NewInt(0)) })))) putDyadic(types.INTEGER, types.INTEGER, ops.Lss, b_(b_i_(b_i_i_(func(l *big.Int, r *big.Int) bool { res := l.Cmp(r) return res == less })))) putDyadic(types.INTEGER, types.INTEGER, ops.Gtr, b_(b_i_(b_i_i_(func(l *big.Int, r *big.Int) bool { res := l.Cmp(r) return res == gtr })))) putDyadic(types.INTEGER, types.INTEGER, ops.Leq, b_(b_i_(b_i_i_(func(l *big.Int, r *big.Int) bool { res := l.Cmp(r) return res != gtr })))) putDyadic(types.INTEGER, types.INTEGER, ops.Geq, b_(b_i_(b_i_i_(func(l *big.Int, r *big.Int) bool { res := l.Cmp(r) return res != less })))) putDyadic(types.INTEGER, types.INTEGER, ops.Eq, b_(b_i_(b_i_i_(func(l *big.Int, r *big.Int) bool { res := l.Cmp(r) return res == eq })))) putDyadic(types.INTEGER, types.INTEGER, ops.Neq, b_(b_i_(b_i_i_(func(l *big.Int, r *big.Int) bool { res := l.Cmp(r) return res != eq })))) }
func (s *Set) Prod(x *Set) { assert.For(x != nil, 20) for _, v := range s.x { if x.In(v) < 0 { s.Excl(v) } } }
func (o *object) InstanceOf(override ...otm.Class) otm.Class { if len(override) > 0 { _, ok := o.clazz.(*class) assert.For(ok, 40, "already instantiated") o.clazz = override[0] } return o.clazz }
func RootOf(o Object) Object { assert.For(!fn.IsNil(o), 20) if fn.IsNil(o.Parent()) { return o } else { return RootOf(o.Parent()) } }
func ThisAny(v *value) (ret *Any) { assert.For(v != nil, 20) if a, ok := v.val.(*Any); ok { ret = &Any{typ: a.typ, x: a.x} } else { ret = &Any{typ: v.typ, x: v.val} } return }
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 (v *value) toCmp() (ret *Cmp) { assert.For(v.typ == types.COMPLEX, 20) switch x := v.val.(type) { case *Cmp: ret = ThisCmp(x) default: halt.As(100, "wrong complex ", reflect.TypeOf(x)) } return }