提交 ee56900e 编写于 作者: 3 3dgen

增加字符串按 rune 遍历(for range迭代)

上级 ae1ddc37
......@@ -42,6 +42,13 @@ func (p *Compiler) Compile(prog *loader.Program, mainFunc string) (output string
}
sort.Strings(pkgnames)
for i, v := range pkgnames {
if v == "runtime" && i != 0 {
pkgnames[i] = pkgnames[0]
pkgnames[0] = "runtime"
}
}
for _, n := range pkgnames {
p.ssaPkg = prog.Pkgs[n].SSAPkg
p.CompilePkgConst(p.ssaPkg)
......
......@@ -359,6 +359,10 @@ func (g *functionGenerator) genValue(v ssa.Value) ([]wat.Inst, wir.ValueType) {
// logger.Printf("Instruction already exist:%s\n", v)
//}
if v, ok := v.(*ssa.Range); ok {
return g.genRange(v)
}
//Todo: 下面的做法过于粗暴
g.tLib.compile(v.Type())
......@@ -419,6 +423,9 @@ func (g *functionGenerator) genValue(v ssa.Value) ([]wat.Inst, wir.ValueType) {
case *ssa.TypeAssert:
return g.genTypeAssert(v)
case *ssa.Next:
return g.genNext(v)
}
logger.Fatalf("Todo: %v, type: %T", v, v)
......@@ -1142,6 +1149,22 @@ func (g *functionGenerator) genTypeAssert(inst *ssa.TypeAssert) (insts []wat.Ins
return
}
func (g *functionGenerator) genRange(inst *ssa.Range) (insts []wat.Inst, ret_type wir.ValueType) {
x := g.getValue(inst.X)
return g.module.EmitGenRange(x.value)
}
func (g *functionGenerator) genNext(inst *ssa.Next) (insts []wat.Inst, ret_type wir.ValueType) {
if inst.IsString {
ret_type = g.tLib.compile(inst.Type())
iter := g.getValue(inst.Iter).value
insts = g.module.EmitGenNext_String(iter)
} else {
logger.Fatalf("Todo:%T", inst.Type())
}
return
}
func (g *functionGenerator) addRegister(typ wir.ValueType) wir.Value {
defer func() { g.cur_local_id++ }()
name := "$t" + strconv.Itoa(g.cur_local_id)
......
......@@ -16,8 +16,8 @@ func (m *Module) EmitAssginValue(lh, rh Value) []wat.Inst {
insts = append(insts, lh.EmitRelease()...)
insts = append(insts, lh.EmitInit()...)
} else {
if !lh.Type().Equal(rh.Type()) {
logger.Fatal("x.Type() != y.Type()")
if !lh.Type().Equal(rh.Type()) && !(lh.Type().Equal(m.I32) && rh.Type().Equal(m.RUNE) || lh.Type().Equal(m.RUNE) && rh.Type().Equal(m.I32)) {
logger.Fatal("x.Type:", lh.Type().Name(), ", y.Type():", rh.Type().Name())
}
insts = append(insts, rh.EmitPush()...)
......@@ -893,6 +893,28 @@ func (m *Module) EmitGenTypeAssert(x Value, destType ValueType, commaOk bool) (i
}
}
func (m *Module) EmitGenRange(x Value) (insts []wat.Inst, ret_type ValueType) {
switch x := x.(type) {
case *aString:
ret_type, _ = m.findValueType("runtime.stringIter")
insts = append(insts, x.Extract("d").EmitPush()...)
insts = append(insts, x.Extract("l").EmitPush()...)
insts = append(insts, wat.NewInstConst(wat.I32{}, "0"))
default:
logger.Fatalf("Todo:%T", x)
}
return
}
func (m *Module) EmitGenNext_String(iter Value) (insts []wat.Inst) {
insts = append(insts, iter.EmitPush()...)
insts = append(insts, wat.NewInstCall("runtime.next_rune"))
insts = append(insts, iter.(*aStruct).Extract("pos").EmitPop()...)
return
}
func (m *Module) EmitInvoke(i Value, params []Value, mid int, typeName string) (insts []wat.Inst) {
iface := i.(*aInterface)
insts = append(insts, iface.Extract("d").EmitPush()...)
......
......@@ -163,3 +163,43 @@ func refToPtr_byteSlice(t: []byte) => i32 {
func refToPtr_string(s: string) => i32 {
return U8_string_to_ptr(s)
}
type stringIter struct {
ptr: uint
len: int
pos: int
}
#wa:runtime_getter
func get_u8(p: u32) => u8
#wa:runtime_setter
func set_u8(p: u32, v: u8)
func next_rune(iter: stringIter) => (ok: bool, k: int, v: rune, pos: int) {
if iter.pos >= iter.len {
return false, iter.pos, 0, iter.pos
}
p0 := i32(get_u8(u32(iter.ptr) + u32(iter.pos)))
if p0 & 0b10000000 == 0 {
return true, iter.pos, rune(p0), iter.pos + 1
} else if p0 & 0b11100000 == 0b11000000 {
p0 = (p0 & 0b11111) << 6
p1 := i32(get_u8(u32(iter.ptr) + u32(iter.pos) + 1)) & 0b00111111
return true, iter.pos, rune(p0 | p1), iter.pos + 2
} else if p0 & 0b11110000 == 0b11100000 {
p0 = (p0 & 0b1111) << 12
p1 := (i32(get_u8(u32(iter.ptr) + u32(iter.pos) + 1)) & 0b00111111) << 6
p2 := (i32(get_u8(u32(iter.ptr) + u32(iter.pos) + 2)) & 0b00111111)
return true, iter.pos, rune(p0 | p1 | p2), iter.pos + 3
} else if p0 & 0b11111000 == 0b11110000 {
p0 = (p0 & 0b111) << 18
p1 := (i32(get_u8(u32(iter.ptr) + u32(iter.pos) + 1)) & 0b00111111) << 12
p2 := (i32(get_u8(u32(iter.ptr) + u32(iter.pos) + 2)) & 0b00111111) << 6
p3 := (i32(get_u8(u32(iter.ptr) + u32(iter.pos) + 3)) & 0b00111111)
return true, iter.pos, rune(p0 | p1 | p2 | p3), iter.pos + 4
}
return
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册