func (p *common) power(b *exprBuilder) { p.cpx(b) for stop := false; !stop; { p.pass(lss.Separator) switch op := p.sym.Code; op { case lss.ArrowUp: p.next() p.pass(lss.Separator) p.cpx(b) b.push(&ir.Dyadic{Op: ops.Map(op)}) default: stop = true } } }
func (p *common) cmp(b *exprBuilder) { p.pass(lss.Separator) p.quantum(b) p.pass(lss.Separator) switch op := p.sym.Code; op { case lss.Equal, lss.Nequal, lss.Geq, lss.Leq, lss.Gtr, lss.Lss, lss.In: p.next() p.pass(lss.Separator) p.quantum(b) b.push(&ir.Dyadic{Op: ops.Map(op)}) case lss.Is: p.next() p.pass(lss.Separator) t := ir.Type{} p.typ(b.tgt.resolve, &t) //second arg b.push(&ir.TypeTest{Typ: t}) case lss.Infixate: p.next() p.expect(lss.Ident, "identifier expected") id := p.ident() p.next() limit := 2 //result + first quantum for stop := false; !stop; { expr := &exprBuilder{tgt: b.tgt, marker: b.marker} p.quantum(expr) b.push(expr) limit++ if p.await(lss.Comma, lss.Separator) { p.next() } else { stop = true } } if def := b.tgt.resolve(id); def != nil { if len(def.Infix()) == 0 { p.mark(def.Name(), " not infixated") } if limit < len(def.Infix()) { p.mark("expected ", len(def.Infix()), " args") } e := &ir.InfixExpr{Unit: def} b.push(e) } else { b.marker.Mark("unit ", id, " not resolved") } } }
func (p *common) product(b *exprBuilder) { p.pass(lss.Separator) p.power(b) for stop := false; !stop; { p.pass(lss.Separator) switch op := p.sym.Code; op { case lss.Times, lss.Div, lss.Mod, lss.Divide, lss.And: p.next() p.pass(lss.Separator) p.power(b) b.push(&ir.Dyadic{Op: ops.Map(op)}) default: stop = true } } }
func (p *common) cpx(b *exprBuilder) { p.factor(b) p.pass(lss.Separator) switch op := p.sym.Code; op { case lss.Ncmp, lss.Pcmp: p.next() p.pass(lss.Separator) if p.sym.Code != lss.Im { p.factor(b) } else { p.mark("imaginary operator not expected") } b.push(&ir.Dyadic{Op: ops.Map(op)}) } }
func (p *common) quantum(b *exprBuilder) { switch { case p.is(lss.Minus): p.next() p.pass(lss.Separator) p.product(b) b.push(&ir.Monadic{Op: ops.Neg}) default: p.pass(lss.Separator) p.product(b) } for stop := false; !stop; { p.pass(lss.Separator) switch op := p.sym.Code; op { case lss.Plus, lss.Minus, lss.Or: p.next() p.pass(lss.Separator) p.product(b) b.push(&ir.Dyadic{Op: ops.Map(op)}) default: stop = true } } }