diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-09-16 15:47:21 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-09-16 15:47:21 +0000 |
commit | 49b4e44b7d540fa846d353b10237848a67789cbf (patch) | |
tree | ea2b52e3c258d6b6d9356977c683c7f72a4a5fd5 /libgo/go/exp | |
parent | 82ceb8f6a88a0193971f53e0571e017f2764f7d7 (diff) | |
download | gcc-49b4e44b7d540fa846d353b10237848a67789cbf.tar.gz |
Update Go library to r60.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@178910 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo/go/exp')
65 files changed, 14724 insertions, 13167 deletions
diff --git a/libgo/go/exp/datafmt/datafmt.go b/libgo/go/exp/datafmt/datafmt.go index a8efdc58fe9..6d7e7644276 100644 --- a/libgo/go/exp/datafmt/datafmt.go +++ b/libgo/go/exp/datafmt/datafmt.go @@ -211,7 +211,6 @@ import ( "runtime" ) - // ---------------------------------------------------------------------------- // Format representation @@ -228,13 +227,11 @@ import ( // type Formatter func(state *State, value interface{}, ruleName string) bool - // A FormatterMap is a set of custom formatters. // It maps a rule name to a formatter function. // type FormatterMap map[string]Formatter - // A parsed format expression is built from the following nodes. // type ( @@ -269,13 +266,11 @@ type ( } ) - // A Format is the result of parsing a format specification. // The format may be applied repeatedly to format values. // type Format map[string]expr - // ---------------------------------------------------------------------------- // Formatting @@ -293,7 +288,6 @@ type Environment interface { Copy() Environment } - // State represents the current formatting state. // It is provided as argument to custom formatters. // @@ -309,7 +303,6 @@ type State struct { separator expr // possibly nil } - func newState(fmt Format, env Environment, errors chan os.Error) *State { s := new(State) s.fmt = fmt @@ -317,12 +310,12 @@ func newState(fmt Format, env Environment, errors chan os.Error) *State { s.errors = errors s.linePos = token.Position{Line: 1} - // if we have a default rule, cache it's expression for fast access + // if we have a default rule, cache its expression for fast access if x, found := fmt["default"]; found { s.default_ = x } - // if we have a global separator rule, cache it's expression for fast access + // if we have a global separator rule, cache its expression for fast access if x, found := fmt["/"]; found { s.separator = x } @@ -330,17 +323,14 @@ func newState(fmt Format, env Environment, errors chan os.Error) *State { return s } - // Env returns the environment passed to Format.Apply. func (s *State) Env() interface{} { return s.env } - // LinePos returns the position of the current line beginning // in the state's output buffer. Line numbers start at 1. // func (s *State) LinePos() token.Position { return s.linePos } - // Pos returns the position of the next byte to be written to the // output buffer. Line numbers start at 1. // @@ -349,7 +339,6 @@ func (s *State) Pos() token.Position { return token.Position{Line: s.linePos.Line, Column: offs - s.linePos.Offset, Offset: offs} } - // Write writes data to the output buffer, inserting the indentation // string after each newline or form feed character. It cannot return an error. // @@ -371,7 +360,6 @@ func (s *State) Write(data []byte) (int, os.Error) { return n + n3, nil } - type checkpoint struct { env Environment hasOutput bool @@ -379,7 +367,6 @@ type checkpoint struct { linePos token.Position } - func (s *State) save() checkpoint { saved := checkpoint{nil, s.hasOutput, s.output.Len(), s.linePos} if s.env != nil { @@ -388,19 +375,16 @@ func (s *State) save() checkpoint { return saved } - func (s *State) restore(m checkpoint) { s.env = m.env s.output.Truncate(m.outputLen) } - func (s *State) error(msg string) { s.errors <- os.NewError(msg) runtime.Goexit() } - // TODO At the moment, unnamed types are simply mapped to the default // names below. For instance, all unnamed arrays are mapped to // 'array' which is not really sufficient. Eventually one may want @@ -440,7 +424,6 @@ func (s *State) getFormat(name string) expr { return nil } - // eval applies a format expression fexpr to a value. If the expression // evaluates internally to a non-nil []byte, that slice is appended to // the state's output buffer and eval returns true. Otherwise, eval @@ -594,7 +577,7 @@ func (s *State) eval(fexpr expr, value reflect.Value, index int) bool { s.eval(t.indent, value, index) // if the indentation evaluates to nil, the state's output buffer // didn't change - either way it's ok to append the difference to - // the current identation + // the current indentation s.indent.Write(s.output.Bytes()[mark.outputLen:s.output.Len()]) s.restore(mark) @@ -653,7 +636,6 @@ func (s *State) eval(fexpr expr, value reflect.Value, index int) bool { return false } - // Eval formats each argument according to the format // f and returns the resulting []byte and os.Error. If // an error occurred, the []byte contains the partially @@ -688,7 +670,6 @@ func (f Format) Eval(env Environment, args ...interface{}) ([]byte, os.Error) { return s.output.Bytes(), err } - // ---------------------------------------------------------------------------- // Convenience functions @@ -705,7 +686,6 @@ func (f Format) Fprint(w io.Writer, env Environment, args ...interface{}) (int, return w.Write(data) } - // Print formats each argument according to the format f // and writes to standard output. The result is the total // number of bytes written and an os.Error, if any. @@ -714,7 +694,6 @@ func (f Format) Print(args ...interface{}) (int, os.Error) { return f.Fprint(os.Stdout, nil, args...) } - // Sprint formats each argument according to the format f // and returns the resulting string. If an error occurs // during formatting, the result string contains the diff --git a/libgo/go/exp/datafmt/datafmt_test.go b/libgo/go/exp/datafmt/datafmt_test.go index d7c70b21dec..87d07165933 100644 --- a/libgo/go/exp/datafmt/datafmt_test.go +++ b/libgo/go/exp/datafmt/datafmt_test.go @@ -10,10 +10,8 @@ import ( "go/token" ) - var fset = token.NewFileSet() - func parse(t *testing.T, form string, fmap FormatterMap) Format { f, err := Parse(fset, "", []byte(form), fmap) if err != nil { @@ -23,7 +21,6 @@ func parse(t *testing.T, form string, fmap FormatterMap) Format { return f } - func verify(t *testing.T, f Format, expected string, args ...interface{}) { if f == nil { return // allow other tests to run @@ -36,7 +33,6 @@ func verify(t *testing.T, f Format, expected string, args ...interface{}) { } } - func formatter(s *State, value interface{}, rule_name string) bool { switch rule_name { case "/": @@ -62,7 +58,6 @@ func formatter(s *State, value interface{}, rule_name string) bool { return false } - func TestCustomFormatters(t *testing.T) { fmap0 := FormatterMap{"/": formatter} fmap1 := FormatterMap{"int": formatter, "blank": formatter, "nil": formatter} @@ -92,7 +87,6 @@ func TestCustomFormatters(t *testing.T) { // TODO needs more tests } - // ---------------------------------------------------------------------------- // Formatting of basic and simple composite types @@ -109,7 +103,6 @@ func check(t *testing.T, form, expected string, args ...interface{}) { } } - func TestBasicTypes(t *testing.T) { check(t, ``, ``) check(t, `bool=":%v"`, `:true:false`, true, false) @@ -144,7 +137,6 @@ func TestBasicTypes(t *testing.T) { check(t, `float64="%g"`, fs, float64(f)) } - func TestArrayTypes(t *testing.T) { var a0 [10]int check(t, `array="array";`, `array`, a0) @@ -159,7 +151,6 @@ func TestArrayTypes(t *testing.T) { check(t, `array={* / ", "}; interface=*; string="bar"; default="%v";`, `42, bar, 3.14`, a2) } - func TestChanTypes(t *testing.T) { var c0 chan int check(t, `chan="chan"`, `chan`, c0) @@ -170,7 +161,6 @@ func TestChanTypes(t *testing.T) { // check(t, `chan=*`, `42`, c1); // reflection support for chans incomplete } - func TestFuncTypes(t *testing.T) { var f0 func() int check(t, `func="func"`, `func`, f0) @@ -180,7 +170,6 @@ func TestFuncTypes(t *testing.T) { // check(t, `func=*`, `42`, f1); // reflection support for funcs incomplete } - func TestMapTypes(t *testing.T) { var m0 map[string]int check(t, `map="map"`, `map`, m0) @@ -190,7 +179,6 @@ func TestMapTypes(t *testing.T) { // check(t, `map=*`, ``, m1); // reflection support for maps incomplete } - func TestPointerTypes(t *testing.T) { var p0 *int check(t, `ptr="ptr"`, `ptr`, p0) @@ -203,7 +191,6 @@ func TestPointerTypes(t *testing.T) { check(t, `ptr=*; int="%d"`, `99991`, p1) } - func TestDefaultRule(t *testing.T) { check(t, `default="%v"`, `42foo3.14`, 42, "foo", 3.14) check(t, `default="%v"; int="%x"`, `abcdef`, 10, 11, 12, 13, 14, 15) @@ -211,13 +198,11 @@ func TestDefaultRule(t *testing.T) { check(t, `default="%x"; int=@:default`, `abcdef`, 10, 11, 12, 13, 14, 15) } - func TestGlobalSeparatorRule(t *testing.T) { check(t, `int="%d"; / ="-"`, `1-2-3-4`, 1, 2, 3, 4) check(t, `int="%x%x"; / ="*"`, `aa*aa`, 10, 10) } - // ---------------------------------------------------------------------------- // Formatting of a struct @@ -231,7 +216,6 @@ const F1 = `datafmt "datafmt";` + func TestStruct1(t *testing.T) { check(t, F1, "<42>", T1{42}) } - // ---------------------------------------------------------------------------- // Formatting of a struct with an optional field (ptr) @@ -256,7 +240,6 @@ func TestStruct2(t *testing.T) { check(t, F2b, "fooempty", T2{"foo", nil}) } - // ---------------------------------------------------------------------------- // Formatting of a struct with a repetitive field (slice) @@ -285,7 +268,6 @@ func TestStruct3(t *testing.T) { check(t, F3b, "bal: 2-3-5", T3{"bal", []int{2, 3, 5}}) } - // ---------------------------------------------------------------------------- // Formatting of a struct with alternative field @@ -318,7 +300,6 @@ func TestStruct4(t *testing.T) { check(t, F4b, "<2, 3, 7>", T4{nil, []int{2, 3, 7}}) } - // ---------------------------------------------------------------------------- // Formatting a struct (documentation example) @@ -338,7 +319,6 @@ func TestStructPoint(t *testing.T) { check(t, FPoint, "---foo---{3, 0xf}", p) } - // ---------------------------------------------------------------------------- // Formatting a slice (documentation example) @@ -347,5 +327,4 @@ const FSlice = `int = "%b";` + func TestSlice(t *testing.T) { check(t, FSlice, "10, 11, 101, 111", []int{2, 3, 5, 7}) } - // TODO add more tests diff --git a/libgo/go/exp/datafmt/parser.go b/libgo/go/exp/datafmt/parser.go index 7dedb531a51..a2ddd389723 100644 --- a/libgo/go/exp/datafmt/parser.go +++ b/libgo/go/exp/datafmt/parser.go @@ -5,7 +5,6 @@ package datafmt import ( - "container/vector" "go/scanner" "go/token" "os" @@ -28,7 +27,6 @@ type parser struct { rules map[string]expr // RuleName -> Expression } - func (p *parser) next() { p.pos, p.tok, p.lit = p.scanner.Scan() switch p.tok { @@ -39,7 +37,6 @@ func (p *parser) next() { } } - func (p *parser) init(fset *token.FileSet, filename string, src []byte) { p.ErrorVector.Reset() p.file = fset.AddFile(filename, fset.Base(), len(src)) @@ -49,12 +46,10 @@ func (p *parser) init(fset *token.FileSet, filename string, src []byte) { p.rules = make(map[string]expr) } - func (p *parser) error(pos token.Pos, msg string) { p.Error(p.file.Position(pos), msg) } - func (p *parser) errorExpected(pos token.Pos, msg string) { msg = "expected " + msg if pos == p.pos { @@ -68,7 +63,6 @@ func (p *parser) errorExpected(pos token.Pos, msg string) { p.error(pos, msg) } - func (p *parser) expect(tok token.Token) token.Pos { pos := p.pos if p.tok != tok { @@ -78,14 +72,12 @@ func (p *parser) expect(tok token.Token) token.Pos { return pos } - func (p *parser) parseIdentifier() string { name := p.lit p.expect(token.IDENT) return name } - func (p *parser) parseTypeName() (string, bool) { pos := p.pos name, isIdent := p.parseIdentifier(), true @@ -102,7 +94,6 @@ func (p *parser) parseTypeName() (string, bool) { return name, isIdent } - // Parses a rule name and returns it. If the rule name is // a package-qualified type name, the package name is resolved. // The 2nd result value is true iff the rule name consists of a @@ -126,7 +117,6 @@ func (p *parser) parseRuleName() (string, bool) { return name, isIdent } - func (p *parser) parseString() string { s := "" if p.tok == token.STRING { @@ -142,7 +132,6 @@ func (p *parser) parseString() string { return s } - func (p *parser) parseLiteral() literal { s := []byte(p.parseString()) @@ -150,14 +139,14 @@ func (p *parser) parseLiteral() literal { // and speed up printing of the literal, split it into segments // that start with "%" possibly followed by a last segment that // starts with some other character. - var list vector.Vector + var list []interface{} i0 := 0 for i := 0; i < len(s); i++ { if s[i] == '%' && i+1 < len(s) { // the next segment starts with a % format if i0 < i { // the current segment is not empty, split it off - list.Push(s[i0:i]) + list = append(list, s[i0:i]) i0 = i } i++ // skip %; let loop skip over char after % @@ -165,18 +154,17 @@ func (p *parser) parseLiteral() literal { } // the final segment may start with any character // (it is empty iff the string is empty) - list.Push(s[i0:]) + list = append(list, s[i0:]) // convert list into a literal - lit := make(literal, list.Len()) - for i := 0; i < list.Len(); i++ { - lit[i] = list.At(i).([]byte) + lit := make(literal, len(list)) + for i := 0; i < len(list); i++ { + lit[i] = list[i].([]byte) } return lit } - func (p *parser) parseField() expr { var fname string switch p.tok { @@ -204,7 +192,6 @@ func (p *parser) parseField() expr { return &field{fname, ruleName} } - func (p *parser) parseOperand() (x expr) { switch p.tok { case token.STRING: @@ -242,38 +229,36 @@ func (p *parser) parseOperand() (x expr) { return x } - func (p *parser) parseSequence() expr { - var list vector.Vector + var list []interface{} for x := p.parseOperand(); x != nil; x = p.parseOperand() { - list.Push(x) + list = append(list, x) } // no need for a sequence if list.Len() < 2 - switch list.Len() { + switch len(list) { case 0: return nil case 1: - return list.At(0).(expr) + return list[0].(expr) } // convert list into a sequence - seq := make(sequence, list.Len()) - for i := 0; i < list.Len(); i++ { - seq[i] = list.At(i).(expr) + seq := make(sequence, len(list)) + for i := 0; i < len(list); i++ { + seq[i] = list[i].(expr) } return seq } - func (p *parser) parseExpression() expr { - var list vector.Vector + var list []interface{} for { x := p.parseSequence() if x != nil { - list.Push(x) + list = append(list, x) } if p.tok != token.OR { break @@ -282,22 +267,21 @@ func (p *parser) parseExpression() expr { } // no need for an alternatives if list.Len() < 2 - switch list.Len() { + switch len(list) { case 0: return nil case 1: - return list.At(0).(expr) + return list[0].(expr) } // convert list into a alternatives - alt := make(alternatives, list.Len()) - for i := 0; i < list.Len(); i++ { - alt[i] = list.At(i).(expr) + alt := make(alternatives, len(list)) + for i := 0; i < len(list); i++ { + alt[i] = list[i].(expr) } return alt } - func (p *parser) parseFormat() { for p.tok != token.EOF { pos := p.pos @@ -343,7 +327,6 @@ func (p *parser) parseFormat() { p.expect(token.EOF) } - func remap(p *parser, name string) string { i := strings.Index(name, ".") if i >= 0 { @@ -359,7 +342,6 @@ func remap(p *parser, name string) string { return name } - // Parse parses a set of format productions from source src. Custom // formatters may be provided via a map of formatter functions. If // there are no errors, the result is a Format and the error is nil. diff --git a/libgo/go/exp/draw/draw.go b/libgo/go/exp/draw/draw.go deleted file mode 100644 index f98e2461894..00000000000 --- a/libgo/go/exp/draw/draw.go +++ /dev/null @@ -1,476 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package draw provides basic graphics and drawing primitives, -// in the style of the Plan 9 graphics library -// (see http://plan9.bell-labs.com/magic/man2html/2/draw) -// and the X Render extension. -package draw - -import ( - "image" - "image/ycbcr" -) - -// m is the maximum color value returned by image.Color.RGBA. -const m = 1<<16 - 1 - -// A Porter-Duff compositing operator. -type Op int - -const ( - // Over specifies ``(src in mask) over dst''. - Over Op = iota - // Src specifies ``src in mask''. - Src -) - -var zeroColor image.Color = image.AlphaColor{0} - -// A draw.Image is an image.Image with a Set method to change a single pixel. -type Image interface { - image.Image - Set(x, y int, c image.Color) -} - -// Draw calls DrawMask with a nil mask and an Over op. -func Draw(dst Image, r image.Rectangle, src image.Image, sp image.Point) { - DrawMask(dst, r, src, sp, nil, image.ZP, Over) -} - -// DrawMask aligns r.Min in dst with sp in src and mp in mask and then replaces the rectangle r -// in dst with the result of a Porter-Duff composition. A nil mask is treated as opaque. -func DrawMask(dst Image, r image.Rectangle, src image.Image, sp image.Point, mask image.Image, mp image.Point, op Op) { - sb := src.Bounds() - dx, dy := sb.Max.X-sp.X, sb.Max.Y-sp.Y - if mask != nil { - mb := mask.Bounds() - if dx > mb.Max.X-mp.X { - dx = mb.Max.X - mp.X - } - if dy > mb.Max.Y-mp.Y { - dy = mb.Max.Y - mp.Y - } - } - if r.Dx() > dx { - r.Max.X = r.Min.X + dx - } - if r.Dy() > dy { - r.Max.Y = r.Min.Y + dy - } - r = r.Intersect(dst.Bounds()) - if r.Empty() { - return - } - - // Fast paths for special cases. If none of them apply, then we fall back to a general but slow implementation. - if dst0, ok := dst.(*image.RGBA); ok { - if op == Over { - if mask == nil { - switch src0 := src.(type) { - case *image.ColorImage: - drawFillOver(dst0, r, src0) - return - case *image.RGBA: - drawCopyOver(dst0, r, src0, sp) - return - case *image.NRGBA: - drawNRGBAOver(dst0, r, src0, sp) - return - case *ycbcr.YCbCr: - drawYCbCr(dst0, r, src0, sp) - return - } - } else if mask0, ok := mask.(*image.Alpha); ok { - switch src0 := src.(type) { - case *image.ColorImage: - drawGlyphOver(dst0, r, src0, mask0, mp) - return - } - } - } else { - if mask == nil { - switch src0 := src.(type) { - case *image.ColorImage: - drawFillSrc(dst0, r, src0) - return - case *image.RGBA: - drawCopySrc(dst0, r, src0, sp) - return - case *image.NRGBA: - drawNRGBASrc(dst0, r, src0, sp) - return - case *ycbcr.YCbCr: - drawYCbCr(dst0, r, src0, sp) - return - } - } - } - drawRGBA(dst0, r, src, sp, mask, mp, op) - return - } - - x0, x1, dx := r.Min.X, r.Max.X, 1 - y0, y1, dy := r.Min.Y, r.Max.Y, 1 - if image.Image(dst) == src && r.Overlaps(r.Add(sp.Sub(r.Min))) { - // Rectangles overlap: process backward? - if sp.Y < r.Min.Y || sp.Y == r.Min.Y && sp.X < r.Min.X { - x0, x1, dx = x1-1, x0-1, -1 - y0, y1, dy = y1-1, y0-1, -1 - } - } - - var out *image.RGBA64Color - sy := sp.Y + y0 - r.Min.Y - my := mp.Y + y0 - r.Min.Y - for y := y0; y != y1; y, sy, my = y+dy, sy+dy, my+dy { - sx := sp.X + x0 - r.Min.X - mx := mp.X + x0 - r.Min.X - for x := x0; x != x1; x, sx, mx = x+dx, sx+dx, mx+dx { - ma := uint32(m) - if mask != nil { - _, _, _, ma = mask.At(mx, my).RGBA() - } - switch { - case ma == 0: - if op == Over { - // No-op. - } else { - dst.Set(x, y, zeroColor) - } - case ma == m && op == Src: - dst.Set(x, y, src.At(sx, sy)) - default: - sr, sg, sb, sa := src.At(sx, sy).RGBA() - if out == nil { - out = new(image.RGBA64Color) - } - if op == Over { - dr, dg, db, da := dst.At(x, y).RGBA() - a := m - (sa * ma / m) - out.R = uint16((dr*a + sr*ma) / m) - out.G = uint16((dg*a + sg*ma) / m) - out.B = uint16((db*a + sb*ma) / m) - out.A = uint16((da*a + sa*ma) / m) - } else { - out.R = uint16(sr * ma / m) - out.G = uint16(sg * ma / m) - out.B = uint16(sb * ma / m) - out.A = uint16(sa * ma / m) - } - dst.Set(x, y, out) - } - } - } -} - -func drawFillOver(dst *image.RGBA, r image.Rectangle, src *image.ColorImage) { - cr, cg, cb, ca := src.RGBA() - // The 0x101 is here for the same reason as in drawRGBA. - a := (m - ca) * 0x101 - x0, x1 := r.Min.X, r.Max.X - y0, y1 := r.Min.Y, r.Max.Y - for y := y0; y != y1; y++ { - dbase := y * dst.Stride - dpix := dst.Pix[dbase+x0 : dbase+x1] - for i, rgba := range dpix { - dr := (uint32(rgba.R)*a)/m + cr - dg := (uint32(rgba.G)*a)/m + cg - db := (uint32(rgba.B)*a)/m + cb - da := (uint32(rgba.A)*a)/m + ca - dpix[i] = image.RGBAColor{uint8(dr >> 8), uint8(dg >> 8), uint8(db >> 8), uint8(da >> 8)} - } - } -} - -func drawCopyOver(dst *image.RGBA, r image.Rectangle, src *image.RGBA, sp image.Point) { - dx0, dx1 := r.Min.X, r.Max.X - dy0, dy1 := r.Min.Y, r.Max.Y - nrows := dy1 - dy0 - sx0, sx1 := sp.X, sp.X+dx1-dx0 - d0 := dy0*dst.Stride + dx0 - d1 := dy0*dst.Stride + dx1 - s0 := sp.Y*src.Stride + sx0 - s1 := sp.Y*src.Stride + sx1 - var ( - ddelta, sdelta int - i0, i1, idelta int - ) - if r.Min.Y < sp.Y || r.Min.Y == sp.Y && r.Min.X <= sp.X { - ddelta = dst.Stride - sdelta = src.Stride - i0, i1, idelta = 0, d1-d0, +1 - } else { - // If the source start point is higher than the destination start point, or equal height but to the left, - // then we compose the rows in right-to-left, bottom-up order instead of left-to-right, top-down. - d0 += (nrows - 1) * dst.Stride - d1 += (nrows - 1) * dst.Stride - s0 += (nrows - 1) * src.Stride - s1 += (nrows - 1) * src.Stride - ddelta = -dst.Stride - sdelta = -src.Stride - i0, i1, idelta = d1-d0-1, -1, -1 - } - for ; nrows > 0; nrows-- { - dpix := dst.Pix[d0:d1] - spix := src.Pix[s0:s1] - for i := i0; i != i1; i += idelta { - // For unknown reasons, even though both dpix[i] and spix[i] are - // image.RGBAColors, on an x86 CPU it seems fastest to call RGBA - // for the source but to do it manually for the destination. - sr, sg, sb, sa := spix[i].RGBA() - rgba := dpix[i] - dr := uint32(rgba.R) - dg := uint32(rgba.G) - db := uint32(rgba.B) - da := uint32(rgba.A) - // The 0x101 is here for the same reason as in drawRGBA. - a := (m - sa) * 0x101 - dr = (dr*a)/m + sr - dg = (dg*a)/m + sg - db = (db*a)/m + sb - da = (da*a)/m + sa - dpix[i] = image.RGBAColor{uint8(dr >> 8), uint8(dg >> 8), uint8(db >> 8), uint8(da >> 8)} - } - d0 += ddelta - d1 += ddelta - s0 += sdelta - s1 += sdelta - } -} - -func drawNRGBAOver(dst *image.RGBA, r image.Rectangle, src *image.NRGBA, sp image.Point) { - for y, sy := r.Min.Y, sp.Y; y != r.Max.Y; y, sy = y+1, sy+1 { - dpix := dst.Pix[y*dst.Stride : (y+1)*dst.Stride] - spix := src.Pix[sy*src.Stride : (sy+1)*src.Stride] - for x, sx := r.Min.X, sp.X; x != r.Max.X; x, sx = x+1, sx+1 { - // Convert from non-premultiplied color to pre-multiplied color. - // The order of operations here is to match the NRGBAColor.RGBA - // method in image/color.go. - snrgba := spix[sx] - sa := uint32(snrgba.A) - sr := uint32(snrgba.R) * 0x101 * sa / 0xff - sg := uint32(snrgba.G) * 0x101 * sa / 0xff - sb := uint32(snrgba.B) * 0x101 * sa / 0xff - sa *= 0x101 - - rgba := dpix[x] - dr := uint32(rgba.R) - dg := uint32(rgba.G) - db := uint32(rgba.B) - da := uint32(rgba.A) - a := (m - sa) * 0x101 - dr = (dr*a + sr*m) / m - dg = (dg*a + sg*m) / m - db = (db*a + sb*m) / m - da = (da*a + sa*m) / m - dpix[x] = image.RGBAColor{uint8(dr >> 8), uint8(dg >> 8), uint8(db >> 8), uint8(da >> 8)} - } - } -} - -func drawGlyphOver(dst *image.RGBA, r image.Rectangle, src *image.ColorImage, mask *image.Alpha, mp image.Point) { - x0, x1 := r.Min.X, r.Max.X - y0, y1 := r.Min.Y, r.Max.Y - cr, cg, cb, ca := src.RGBA() - for y, my := y0, mp.Y; y != y1; y, my = y+1, my+1 { - dbase := y * dst.Stride - dpix := dst.Pix[dbase+x0 : dbase+x1] - mbase := my * mask.Stride - mpix := mask.Pix[mbase+mp.X:] - for i, rgba := range dpix { - ma := uint32(mpix[i].A) - if ma == 0 { - continue - } - ma |= ma << 8 - dr := uint32(rgba.R) - dg := uint32(rgba.G) - db := uint32(rgba.B) - da := uint32(rgba.A) - // The 0x101 is here for the same reason as in drawRGBA. - a := (m - (ca * ma / m)) * 0x101 - dr = (dr*a + cr*ma) / m - dg = (dg*a + cg*ma) / m - db = (db*a + cb*ma) / m - da = (da*a + ca*ma) / m - dpix[i] = image.RGBAColor{uint8(dr >> 8), uint8(dg >> 8), uint8(db >> 8), uint8(da >> 8)} - } - } -} - -func drawFillSrc(dst *image.RGBA, r image.Rectangle, src *image.ColorImage) { - if r.Dy() < 1 { - return - } - cr, cg, cb, ca := src.RGBA() - color := image.RGBAColor{uint8(cr >> 8), uint8(cg >> 8), uint8(cb >> 8), uint8(ca >> 8)} - // The built-in copy function is faster than a straightforward for loop to fill the destination with - // the color, but copy requires a slice source. We therefore use a for loop to fill the first row, and - // then use the first row as the slice source for the remaining rows. - dx0, dx1 := r.Min.X, r.Max.X - dy0, dy1 := r.Min.Y, r.Max.Y - dbase := dy0 * dst.Stride - i0, i1 := dbase+dx0, dbase+dx1 - firstRow := dst.Pix[i0:i1] - for i := range firstRow { - firstRow[i] = color - } - for y := dy0 + 1; y < dy1; y++ { - i0 += dst.Stride - i1 += dst.Stride - copy(dst.Pix[i0:i1], firstRow) - } -} - -func drawCopySrc(dst *image.RGBA, r image.Rectangle, src *image.RGBA, sp image.Point) { - dx0, dx1 := r.Min.X, r.Max.X - dy0, dy1 := r.Min.Y, r.Max.Y - nrows := dy1 - dy0 - sx0, sx1 := sp.X, sp.X+dx1-dx0 - d0 := dy0*dst.Stride + dx0 - d1 := dy0*dst.Stride + dx1 - s0 := sp.Y*src.Stride + sx0 - s1 := sp.Y*src.Stride + sx1 - var ddelta, sdelta int - if r.Min.Y <= sp.Y { - ddelta = dst.Stride - sdelta = src.Stride - } else { - // If the source start point is higher than the destination start point, then we compose the rows - // in bottom-up order instead of top-down. Unlike the drawCopyOver function, we don't have to - // check the x co-ordinates because the built-in copy function can handle overlapping slices. - d0 += (nrows - 1) * dst.Stride - d1 += (nrows - 1) * dst.Stride - s0 += (nrows - 1) * src.Stride - s1 += (nrows - 1) * src.Stride - ddelta = -dst.Stride - sdelta = -src.Stride - } - for ; nrows > 0; nrows-- { - copy(dst.Pix[d0:d1], src.Pix[s0:s1]) - d0 += ddelta - d1 += ddelta - s0 += sdelta - s1 += sdelta - } -} - -func drawNRGBASrc(dst *image.RGBA, r image.Rectangle, src *image.NRGBA, sp image.Point) { - for y, sy := r.Min.Y, sp.Y; y != r.Max.Y; y, sy = y+1, sy+1 { - dpix := dst.Pix[y*dst.Stride : (y+1)*dst.Stride] - spix := src.Pix[sy*src.Stride : (sy+1)*src.Stride] - for x, sx := r.Min.X, sp.X; x != r.Max.X; x, sx = x+1, sx+1 { - // Convert from non-premultiplied color to pre-multiplied color. - // The order of operations here is to match the NRGBAColor.RGBA - // method in image/color.go. - snrgba := spix[sx] - sa := uint32(snrgba.A) - sr := uint32(snrgba.R) * 0x101 * sa / 0xff - sg := uint32(snrgba.G) * 0x101 * sa / 0xff - sb := uint32(snrgba.B) * 0x101 * sa / 0xff - sa *= 0x101 - - dpix[x] = image.RGBAColor{uint8(sr >> 8), uint8(sg >> 8), uint8(sb >> 8), uint8(sa >> 8)} - } - } -} - -func drawYCbCr(dst *image.RGBA, r image.Rectangle, src *ycbcr.YCbCr, sp image.Point) { - // A YCbCr image is always fully opaque, and so if the mask is implicitly nil - // (i.e. fully opaque) then the op is effectively always Src. - var ( - yy, cb, cr uint8 - rr, gg, bb uint8 - ) - switch src.SubsampleRatio { - case ycbcr.SubsampleRatio422: - for y, sy := r.Min.Y, sp.Y; y != r.Max.Y; y, sy = y+1, sy+1 { - dpix := dst.Pix[y*dst.Stride : (y+1)*dst.Stride] - for x, sx := r.Min.X, sp.X; x != r.Max.X; x, sx = x+1, sx+1 { - i := sx / 2 - yy = src.Y[sy*src.YStride+sx] - cb = src.Cb[sy*src.CStride+i] - cr = src.Cr[sy*src.CStride+i] - rr, gg, bb = ycbcr.YCbCrToRGB(yy, cb, cr) - dpix[x] = image.RGBAColor{rr, gg, bb, 255} - } - } - case ycbcr.SubsampleRatio420: - for y, sy := r.Min.Y, sp.Y; y != r.Max.Y; y, sy = y+1, sy+1 { - dpix := dst.Pix[y*dst.Stride : (y+1)*dst.Stride] - for x, sx := r.Min.X, sp.X; x != r.Max.X; x, sx = x+1, sx+1 { - i, j := sx/2, sy/2 - yy = src.Y[sy*src.YStride+sx] - cb = src.Cb[j*src.CStride+i] - cr = src.Cr[j*src.CStride+i] - rr, gg, bb = ycbcr.YCbCrToRGB(yy, cb, cr) - dpix[x] = image.RGBAColor{rr, gg, bb, 255} - } - } - default: - // Default to 4:4:4 subsampling. - for y, sy := r.Min.Y, sp.Y; y != r.Max.Y; y, sy = y+1, sy+1 { - dpix := dst.Pix[y*dst.Stride : (y+1)*dst.Stride] - for x, sx := r.Min.X, sp.X; x != r.Max.X; x, sx = x+1, sx+1 { - yy = src.Y[sy*src.YStride+sx] - cb = src.Cb[sy*src.CStride+sx] - cr = src.Cr[sy*src.CStride+sx] - rr, gg, bb = ycbcr.YCbCrToRGB(yy, cb, cr) - dpix[x] = image.RGBAColor{rr, gg, bb, 255} - } - } - } -} - -func drawRGBA(dst *image.RGBA, r image.Rectangle, src image.Image, sp image.Point, mask image.Image, mp image.Point, op Op) { - x0, x1, dx := r.Min.X, r.Max.X, 1 - y0, y1, dy := r.Min.Y, r.Max.Y, 1 - if image.Image(dst) == src && r.Overlaps(r.Add(sp.Sub(r.Min))) { - if sp.Y < r.Min.Y || sp.Y == r.Min.Y && sp.X < r.Min.X { - x0, x1, dx = x1-1, x0-1, -1 - y0, y1, dy = y1-1, y0-1, -1 - } - } - - sy := sp.Y + y0 - r.Min.Y - my := mp.Y + y0 - r.Min.Y - for y := y0; y != y1; y, sy, my = y+dy, sy+dy, my+dy { - sx := sp.X + x0 - r.Min.X - mx := mp.X + x0 - r.Min.X - dpix := dst.Pix[y*dst.Stride : (y+1)*dst.Stride] - for x := x0; x != x1; x, sx, mx = x+dx, sx+dx, mx+dx { - ma := uint32(m) - if mask != nil { - _, _, _, ma = mask.At(mx, my).RGBA() - } - sr, sg, sb, sa := src.At(sx, sy).RGBA() - var dr, dg, db, da uint32 - if op == Over { - rgba := dpix[x] - dr = uint32(rgba.R) - dg = uint32(rgba.G) - db = uint32(rgba.B) - da = uint32(rgba.A) - // dr, dg, db and da are all 8-bit color at the moment, ranging in [0,255]. - // We work in 16-bit color, and so would normally do: - // dr |= dr << 8 - // and similarly for dg, db and da, but instead we multiply a - // (which is a 16-bit color, ranging in [0,65535]) by 0x101. - // This yields the same result, but is fewer arithmetic operations. - a := (m - (sa * ma / m)) * 0x101 - dr = (dr*a + sr*ma) / m - dg = (dg*a + sg*ma) / m - db = (db*a + sb*ma) / m - da = (da*a + sa*ma) / m - } else { - dr = sr * ma / m - dg = sg * ma / m - db = sb * ma / m - da = sa * ma / m - } - dpix[x] = image.RGBAColor{uint8(dr >> 8), uint8(dg >> 8), uint8(db >> 8), uint8(da >> 8)} - } - } -} diff --git a/libgo/go/exp/draw/draw_test.go b/libgo/go/exp/draw/draw_test.go deleted file mode 100644 index 873a2f24a40..00000000000 --- a/libgo/go/exp/draw/draw_test.go +++ /dev/null @@ -1,278 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package draw - -import ( - "image" - "image/ycbcr" - "testing" -) - -func eq(c0, c1 image.Color) bool { - r0, g0, b0, a0 := c0.RGBA() - r1, g1, b1, a1 := c1.RGBA() - return r0 == r1 && g0 == g1 && b0 == b1 && a0 == a1 -} - -func fillBlue(alpha int) image.Image { - return image.NewColorImage(image.RGBAColor{0, 0, uint8(alpha), uint8(alpha)}) -} - -func fillAlpha(alpha int) image.Image { - return image.NewColorImage(image.AlphaColor{uint8(alpha)}) -} - -func vgradGreen(alpha int) image.Image { - m := image.NewRGBA(16, 16) - for y := 0; y < 16; y++ { - for x := 0; x < 16; x++ { - m.Set(x, y, image.RGBAColor{0, uint8(y * alpha / 15), 0, uint8(alpha)}) - } - } - return m -} - -func vgradAlpha(alpha int) image.Image { - m := image.NewAlpha(16, 16) - for y := 0; y < 16; y++ { - for x := 0; x < 16; x++ { - m.Set(x, y, image.AlphaColor{uint8(y * alpha / 15)}) - } - } - return m -} - -func vgradGreenNRGBA(alpha int) image.Image { - m := image.NewNRGBA(16, 16) - for y := 0; y < 16; y++ { - for x := 0; x < 16; x++ { - m.Set(x, y, image.RGBAColor{0, uint8(y * 0x11), 0, uint8(alpha)}) - } - } - return m -} - -func vgradCr() image.Image { - m := &ycbcr.YCbCr{ - Y: make([]byte, 16*16), - Cb: make([]byte, 16*16), - Cr: make([]byte, 16*16), - YStride: 16, - CStride: 16, - SubsampleRatio: ycbcr.SubsampleRatio444, - Rect: image.Rect(0, 0, 16, 16), - } - for y := 0; y < 16; y++ { - for x := 0; x < 16; x++ { - m.Cr[y*m.CStride+x] = uint8(y * 0x11) - } - } - return m -} - -func hgradRed(alpha int) Image { - m := image.NewRGBA(16, 16) - for y := 0; y < 16; y++ { - for x := 0; x < 16; x++ { - m.Set(x, y, image.RGBAColor{uint8(x * alpha / 15), 0, 0, uint8(alpha)}) - } - } - return m -} - -func gradYellow(alpha int) Image { - m := image.NewRGBA(16, 16) - for y := 0; y < 16; y++ { - for x := 0; x < 16; x++ { - m.Set(x, y, image.RGBAColor{uint8(x * alpha / 15), uint8(y * alpha / 15), 0, uint8(alpha)}) - } - } - return m -} - -type drawTest struct { - desc string - src image.Image - mask image.Image - op Op - expected image.Color -} - -var drawTests = []drawTest{ - // Uniform mask (0% opaque). - {"nop", vgradGreen(255), fillAlpha(0), Over, image.RGBAColor{136, 0, 0, 255}}, - {"clear", vgradGreen(255), fillAlpha(0), Src, image.RGBAColor{0, 0, 0, 0}}, - // Uniform mask (100%, 75%, nil) and uniform source. - // At (x, y) == (8, 8): - // The destination pixel is {136, 0, 0, 255}. - // The source pixel is {0, 0, 90, 90}. - {"fill", fillBlue(90), fillAlpha(255), Over, image.RGBAColor{88, 0, 90, 255}}, - {"fillSrc", fillBlue(90), fillAlpha(255), Src, image.RGBAColor{0, 0, 90, 90}}, - {"fillAlpha", fillBlue(90), fillAlpha(192), Over, image.RGBAColor{100, 0, 68, 255}}, - {"fillAlphaSrc", fillBlue(90), fillAlpha(192), Src, image.RGBAColor{0, 0, 68, 68}}, - {"fillNil", fillBlue(90), nil, Over, image.RGBAColor{88, 0, 90, 255}}, - {"fillNilSrc", fillBlue(90), nil, Src, image.RGBAColor{0, 0, 90, 90}}, - // Uniform mask (100%, 75%, nil) and variable source. - // At (x, y) == (8, 8): - // The destination pixel is {136, 0, 0, 255}. - // The source pixel is {0, 48, 0, 90}. - {"copy", vgradGreen(90), fillAlpha(255), Over, image.RGBAColor{88, 48, 0, 255}}, - {"copySrc", vgradGreen(90), fillAlpha(255), Src, image.RGBAColor{0, 48, 0, 90}}, - {"copyAlpha", vgradGreen(90), fillAlpha(192), Over, image.RGBAColor{100, 36, 0, 255}}, - {"copyAlphaSrc", vgradGreen(90), fillAlpha(192), Src, image.RGBAColor{0, 36, 0, 68}}, - {"copyNil", vgradGreen(90), nil, Over, image.RGBAColor{88, 48, 0, 255}}, - {"copyNilSrc", vgradGreen(90), nil, Src, image.RGBAColor{0, 48, 0, 90}}, - // Uniform mask (100%, 75%, nil) and variable NRGBA source. - // At (x, y) == (8, 8): - // The destination pixel is {136, 0, 0, 255}. - // The source pixel is {0, 136, 0, 90} in NRGBA-space, which is {0, 48, 0, 90} in RGBA-space. - // The result pixel is different than in the "copy*" test cases because of rounding errors. - {"nrgba", vgradGreenNRGBA(90), fillAlpha(255), Over, image.RGBAColor{88, 46, 0, 255}}, - {"nrgbaSrc", vgradGreenNRGBA(90), fillAlpha(255), Src, image.RGBAColor{0, 46, 0, 90}}, - {"nrgbaAlpha", vgradGreenNRGBA(90), fillAlpha(192), Over, image.RGBAColor{100, 34, 0, 255}}, - {"nrgbaAlphaSrc", vgradGreenNRGBA(90), fillAlpha(192), Src, image.RGBAColor{0, 34, 0, 68}}, - {"nrgbaNil", vgradGreenNRGBA(90), nil, Over, image.RGBAColor{88, 46, 0, 255}}, - {"nrgbaNilSrc", vgradGreenNRGBA(90), nil, Src, image.RGBAColor{0, 46, 0, 90}}, - // Uniform mask (100%, 75%, nil) and variable YCbCr source. - // At (x, y) == (8, 8): - // The destination pixel is {136, 0, 0, 255}. - // The source pixel is {0, 0, 136} in YCbCr-space, which is {11, 38, 0, 255} in RGB-space. - {"ycbcr", vgradCr(), fillAlpha(255), Over, image.RGBAColor{11, 38, 0, 255}}, - {"ycbcrSrc", vgradCr(), fillAlpha(255), Src, image.RGBAColor{11, 38, 0, 255}}, - {"ycbcrAlpha", vgradCr(), fillAlpha(192), Over, image.RGBAColor{42, 28, 0, 255}}, - {"ycbcrAlphaSrc", vgradCr(), fillAlpha(192), Src, image.RGBAColor{8, 28, 0, 192}}, - {"ycbcrNil", vgradCr(), nil, Over, image.RGBAColor{11, 38, 0, 255}}, - {"ycbcrNilSrc", vgradCr(), nil, Src, image.RGBAColor{11, 38, 0, 255}}, - // Variable mask and variable source. - // At (x, y) == (8, 8): - // The destination pixel is {136, 0, 0, 255}. - // The source pixel is {0, 0, 255, 255}. - // The mask pixel's alpha is 102, or 40%. - {"generic", fillBlue(255), vgradAlpha(192), Over, image.RGBAColor{81, 0, 102, 255}}, - {"genericSrc", fillBlue(255), vgradAlpha(192), Src, image.RGBAColor{0, 0, 102, 102}}, -} - -func makeGolden(dst, src, mask image.Image, op Op) image.Image { - // Since golden is a newly allocated image, we don't have to check if the - // input source and mask images and the output golden image overlap. - b := dst.Bounds() - sx0 := src.Bounds().Min.X - b.Min.X - sy0 := src.Bounds().Min.Y - b.Min.Y - var mx0, my0 int - if mask != nil { - mx0 = mask.Bounds().Min.X - b.Min.X - my0 = mask.Bounds().Min.Y - b.Min.Y - } - golden := image.NewRGBA(b.Max.X, b.Max.Y) - for y := b.Min.Y; y < b.Max.Y; y++ { - my, sy := my0+y, sy0+y - for x := b.Min.X; x < b.Max.X; x++ { - mx, sx := mx0+x, sx0+x - const M = 1<<16 - 1 - var dr, dg, db, da uint32 - if op == Over { - dr, dg, db, da = dst.At(x, y).RGBA() - } - sr, sg, sb, sa := src.At(sx, sy).RGBA() - ma := uint32(M) - if mask != nil { - _, _, _, ma = mask.At(mx, my).RGBA() - } - a := M - (sa * ma / M) - golden.Set(x, y, image.RGBA64Color{ - uint16((dr*a + sr*ma) / M), - uint16((dg*a + sg*ma) / M), - uint16((db*a + sb*ma) / M), - uint16((da*a + sa*ma) / M), - }) - } - } - golden.Rect = b - return golden -} - -func TestDraw(t *testing.T) { -loop: - for _, test := range drawTests { - dst := hgradRed(255) - // Draw the (src, mask, op) onto a copy of dst using a slow but obviously correct implementation. - golden := makeGolden(dst, test.src, test.mask, test.op) - b := dst.Bounds() - if !b.Eq(golden.Bounds()) { - t.Errorf("draw %s: bounds %v versus %v", test.desc, dst.Bounds(), golden.Bounds()) - continue - } - // Draw the same combination onto the actual dst using the optimized DrawMask implementation. - DrawMask(dst, b, test.src, image.ZP, test.mask, image.ZP, test.op) - // Check that the resultant pixel at (8, 8) matches what we expect - // (the expected value can be verified by hand). - if !eq(dst.At(8, 8), test.expected) { - t.Errorf("draw %s: at (8, 8) %v versus %v", test.desc, dst.At(8, 8), test.expected) - continue - } - // Check that the resultant dst image matches the golden output. - for y := b.Min.Y; y < b.Max.Y; y++ { - for x := b.Min.X; x < b.Max.X; x++ { - if !eq(dst.At(x, y), golden.At(x, y)) { - t.Errorf("draw %s: at (%d, %d), %v versus golden %v", test.desc, x, y, dst.At(x, y), golden.At(x, y)) - continue loop - } - } - } - } -} - -func TestDrawOverlap(t *testing.T) { - for _, op := range []Op{Over, Src} { - for yoff := -2; yoff <= 2; yoff++ { - loop: - for xoff := -2; xoff <= 2; xoff++ { - m := gradYellow(127).(*image.RGBA) - dst := &image.RGBA{ - Pix: m.Pix, - Stride: m.Stride, - Rect: image.Rect(5, 5, 10, 10), - } - src := &image.RGBA{ - Pix: m.Pix, - Stride: m.Stride, - Rect: image.Rect(5+xoff, 5+yoff, 10+xoff, 10+yoff), - } - // Draw the (src, mask, op) onto a copy of dst using a slow but obviously correct implementation. - golden := makeGolden(dst, src, nil, op) - b := dst.Bounds() - if !b.Eq(golden.Bounds()) { - t.Errorf("drawOverlap xoff=%d,yoff=%d: bounds %v versus %v", xoff, yoff, dst.Bounds(), golden.Bounds()) - continue - } - // Draw the same combination onto the actual dst using the optimized DrawMask implementation. - DrawMask(dst, b, src, src.Bounds().Min, nil, image.ZP, op) - // Check that the resultant dst image matches the golden output. - for y := b.Min.Y; y < b.Max.Y; y++ { - for x := b.Min.X; x < b.Max.X; x++ { - if !eq(dst.At(x, y), golden.At(x, y)) { - t.Errorf("drawOverlap xoff=%d,yoff=%d: at (%d, %d), %v versus golden %v", xoff, yoff, x, y, dst.At(x, y), golden.At(x, y)) - continue loop - } - } - } - } - } - } -} - -// TestIssue836 verifies http://code.google.com/p/go/issues/detail?id=836. -func TestIssue836(t *testing.T) { - a := image.NewRGBA(1, 1) - b := image.NewRGBA(2, 2) - b.Set(0, 0, image.RGBAColor{0, 0, 0, 5}) - b.Set(1, 0, image.RGBAColor{0, 0, 5, 5}) - b.Set(0, 1, image.RGBAColor{0, 5, 0, 5}) - b.Set(1, 1, image.RGBAColor{5, 0, 0, 5}) - Draw(a, image.Rect(0, 0, 1, 1), b, image.Pt(1, 1)) - if !eq(image.RGBAColor{5, 0, 0, 5}, a.At(0, 0)) { - t.Errorf("Issue 836: want %v got %v", image.RGBAColor{5, 0, 0, 5}, a.At(0, 0)) - } -} diff --git a/libgo/go/exp/eval/abort.go b/libgo/go/exp/eval/abort.go deleted file mode 100644 index 22e17cec405..00000000000 --- a/libgo/go/exp/eval/abort.go +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package eval - -import ( - "fmt" - "os" - "runtime" -) - -// Abort aborts the thread's current computation, -// causing the innermost Try to return err. -func (t *Thread) Abort(err os.Error) { - if t.abort == nil { - panic("abort: " + err.String()) - } - t.abort <- err - runtime.Goexit() -} - -// Try executes a computation; if the computation -// Aborts, Try returns the error passed to abort. -func (t *Thread) Try(f func(t *Thread)) os.Error { - oc := t.abort - c := make(chan os.Error) - t.abort = c - go func() { - f(t) - c <- nil - }() - err := <-c - t.abort = oc - return err -} - -type DivByZeroError struct{} - -func (DivByZeroError) String() string { return "divide by zero" } - -type NilPointerError struct{} - -func (NilPointerError) String() string { return "nil pointer dereference" } - -type IndexError struct { - Idx, Len int64 -} - -func (e IndexError) String() string { - if e.Idx < 0 { - return fmt.Sprintf("negative index: %d", e.Idx) - } - return fmt.Sprintf("index %d exceeds length %d", e.Idx, e.Len) -} - -type SliceError struct { - Lo, Hi, Cap int64 -} - -func (e SliceError) String() string { - return fmt.Sprintf("slice [%d:%d]; cap %d", e.Lo, e.Hi, e.Cap) -} - -type KeyError struct { - Key interface{} -} - -func (e KeyError) String() string { return fmt.Sprintf("key '%v' not found in map", e.Key) } - -type NegativeLengthError struct { - Len int64 -} - -func (e NegativeLengthError) String() string { - return fmt.Sprintf("negative length: %d", e.Len) -} - -type NegativeCapacityError struct { - Len int64 -} - -func (e NegativeCapacityError) String() string { - return fmt.Sprintf("negative capacity: %d", e.Len) -} diff --git a/libgo/go/exp/eval/bridge.go b/libgo/go/exp/eval/bridge.go deleted file mode 100644 index f31d9ab9bd6..00000000000 --- a/libgo/go/exp/eval/bridge.go +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package eval - -import ( - "log" - "go/token" - "reflect" -) - -/* - * Type bridging - */ - -var ( - evalTypes = make(map[reflect.Type]Type) - nativeTypes = make(map[Type]reflect.Type) -) - -// TypeFromNative converts a regular Go type into a the corresponding -// interpreter Type. -func TypeFromNative(t reflect.Type) Type { - if et, ok := evalTypes[t]; ok { - return et - } - - var nt *NamedType - if t.Name() != "" { - name := t.PkgPath() + "·" + t.Name() - nt = &NamedType{token.NoPos, name, nil, true, make(map[string]Method)} - evalTypes[t] = nt - } - - var et Type - switch t.Kind() { - case reflect.Bool: - et = BoolType - - case reflect.Float32: - et = Float32Type - case reflect.Float64: - et = Float64Type - - case reflect.Int16: - et = Int16Type - case reflect.Int32: - et = Int32Type - case reflect.Int64: - et = Int64Type - case reflect.Int8: - et = Int8Type - case reflect.Int: - et = IntType - - case reflect.Uint16: - et = Uint16Type - case reflect.Uint32: - et = Uint32Type - case reflect.Uint64: - et = Uint64Type - case reflect.Uint8: - et = Uint8Type - case reflect.Uint: - et = UintType - case reflect.Uintptr: - et = UintptrType - - case reflect.String: - et = StringType - case reflect.Array: - et = NewArrayType(int64(t.Len()), TypeFromNative(t.Elem())) - case reflect.Chan: - log.Panicf("%T not implemented", t) - case reflect.Func: - nin := t.NumIn() - // Variadic functions have DotDotDotType at the end - variadic := t.IsVariadic() - if variadic { - nin-- - } - in := make([]Type, nin) - for i := range in { - in[i] = TypeFromNative(t.In(i)) - } - out := make([]Type, t.NumOut()) - for i := range out { - out[i] = TypeFromNative(t.Out(i)) - } - et = NewFuncType(in, variadic, out) - case reflect.Interface: - log.Panicf("%T not implemented", t) - case reflect.Map: - log.Panicf("%T not implemented", t) - case reflect.Ptr: - et = NewPtrType(TypeFromNative(t.Elem())) - case reflect.Slice: - et = NewSliceType(TypeFromNative(t.Elem())) - case reflect.Struct: - n := t.NumField() - fields := make([]StructField, n) - for i := 0; i < n; i++ { - sf := t.Field(i) - // TODO(austin) What to do about private fields? - fields[i].Name = sf.Name - fields[i].Type = TypeFromNative(sf.Type) - fields[i].Anonymous = sf.Anonymous - } - et = NewStructType(fields) - case reflect.UnsafePointer: - log.Panicf("%T not implemented", t) - default: - log.Panicf("unexpected reflect.Type: %T", t) - } - - if nt != nil { - if _, ok := et.(*NamedType); !ok { - nt.Complete(et) - et = nt - } - } - - nativeTypes[et] = t - evalTypes[t] = et - - return et -} - -// TypeOfNative returns the interpreter Type of a regular Go value. -func TypeOfNative(v interface{}) Type { return TypeFromNative(reflect.TypeOf(v)) } - -/* - * Function bridging - */ - -type nativeFunc struct { - fn func(*Thread, []Value, []Value) - in, out int -} - -func (f *nativeFunc) NewFrame() *Frame { - vars := make([]Value, f.in+f.out) - return &Frame{nil, vars} -} - -func (f *nativeFunc) Call(t *Thread) { f.fn(t, t.f.Vars[0:f.in], t.f.Vars[f.in:f.in+f.out]) } - -// FuncFromNative creates an interpreter function from a native -// function that takes its in and out arguments as slices of -// interpreter Value's. While somewhat inconvenient, this avoids -// value marshalling. -func FuncFromNative(fn func(*Thread, []Value, []Value), t *FuncType) FuncValue { - return &funcV{&nativeFunc{fn, len(t.In), len(t.Out)}} -} - -// FuncFromNativeTyped is like FuncFromNative, but constructs the -// function type from a function pointer using reflection. Typically, -// the type will be given as a nil pointer to a function with the -// desired signature. -func FuncFromNativeTyped(fn func(*Thread, []Value, []Value), t interface{}) (*FuncType, FuncValue) { - ft := TypeOfNative(t).(*FuncType) - return ft, FuncFromNative(fn, ft) -} diff --git a/libgo/go/exp/eval/compiler.go b/libgo/go/exp/eval/compiler.go deleted file mode 100644 index 9d2923bfca4..00000000000 --- a/libgo/go/exp/eval/compiler.go +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package eval - -import ( - "fmt" - "go/scanner" - "go/token" -) - - -// A compiler captures information used throughout an entire -// compilation. Currently it includes only the error handler. -// -// TODO(austin) This might actually represent package level, in which -// case it should be package compiler. -type compiler struct { - fset *token.FileSet - errors scanner.ErrorHandler - numErrors int - silentErrors int -} - -func (a *compiler) diagAt(pos token.Pos, format string, args ...interface{}) { - a.errors.Error(a.fset.Position(pos), fmt.Sprintf(format, args...)) - a.numErrors++ -} - -func (a *compiler) numError() int { return a.numErrors + a.silentErrors } - -// The universal scope -func newUniverse() *Scope { - sc := &Scope{nil, 0} - sc.block = &block{ - offset: 0, - scope: sc, - global: true, - defs: make(map[string]Def), - } - return sc -} - -var universe *Scope = newUniverse() - - -// TODO(austin) These can all go in stmt.go now -type label struct { - name string - desc string - // The PC goto statements should jump to, or nil if this label - // cannot be goto'd (such as an anonymous for loop label). - gotoPC *uint - // The PC break statements should jump to, or nil if a break - // statement is invalid. - breakPC *uint - // The PC continue statements should jump to, or nil if a - // continue statement is invalid. - continuePC *uint - // The position where this label was resolved. If it has not - // been resolved yet, an invalid position. - resolved token.Pos - // The position where this label was first jumped to. - used token.Pos -} - -// A funcCompiler captures information used throughout the compilation -// of a single function body. -type funcCompiler struct { - *compiler - fnType *FuncType - // Whether the out variables are named. This affects what - // kinds of return statements are legal. - outVarsNamed bool - *codeBuf - flow *flowBuf - labels map[string]*label -} - -// A blockCompiler captures information used throughout the compilation -// of a single block within a function. -type blockCompiler struct { - *funcCompiler - block *block - // The label of this block, used for finding break and - // continue labels. - label *label - // The blockCompiler for the block enclosing this one, or nil - // for a function-level block. - parent *blockCompiler -} diff --git a/libgo/go/exp/eval/eval_test.go b/libgo/go/exp/eval/eval_test.go deleted file mode 100644 index 541d3feb71d..00000000000 --- a/libgo/go/exp/eval/eval_test.go +++ /dev/null @@ -1,263 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package eval - -import ( - "big" - "flag" - "fmt" - "go/token" - "log" - "os" - "reflect" - "regexp" - "testing" -) - -// All tests are done using the same file set. -var fset = token.NewFileSet() - -// Print each statement or expression before parsing it -var noisy = false - -func init() { flag.BoolVar(&noisy, "noisy", false, "chatter during eval tests") } - -/* - * Generic statement/expression test framework - */ - -type test []job - -type job struct { - code string - cerr string - rterr string - val Value - noval bool -} - -func runTests(t *testing.T, baseName string, tests []test) { - delta := 1 - if testing.Short() { - delta = 16 - } - for i := 0; i < len(tests); i += delta { - name := fmt.Sprintf("%s[%d]", baseName, i) - tests[i].run(t, name) - } -} - -func (a test) run(t *testing.T, name string) { - w := newTestWorld() - for _, j := range a { - src := j.code + ";" // trailing semicolon to finish statement - if noisy { - println("code:", src) - } - - code, err := w.Compile(fset, src) - if err != nil { - if j.cerr == "" { - t.Errorf("%s: Compile %s: %v", name, src, err) - break - } - if !match(t, err, j.cerr) { - t.Errorf("%s: Compile %s = error %s; want %v", name, src, err, j.cerr) - break - } - continue - } - if j.cerr != "" { - t.Errorf("%s: Compile %s succeeded; want %s", name, src, j.cerr) - break - } - - val, err := code.Run() - if err != nil { - if j.rterr == "" { - t.Errorf("%s: Run %s: %v", name, src, err) - break - } - if !match(t, err, j.rterr) { - t.Errorf("%s: Run %s = error %s; want %v", name, src, err, j.rterr) - break - } - continue - } - if j.rterr != "" { - t.Errorf("%s: Run %s succeeded; want %s", name, src, j.rterr) - break - } - - if !j.noval && !reflect.DeepEqual(val, j.val) { - t.Errorf("%s: Run %s = %T(%v) want %T(%v)", name, src, val, val, j.val, j.val) - } - } -} - -func match(t *testing.T, err os.Error, pat string) bool { - ok, err1 := regexp.MatchString(pat, err.String()) - if err1 != nil { - t.Fatalf("compile regexp %s: %v", pat, err1) - } - return ok -} - - -/* - * Test constructors - */ - -// Expression compile error -func CErr(expr string, cerr string) test { return test([]job{{code: expr, cerr: cerr}}) } - -// Expression runtime error -func RErr(expr string, rterr string) test { return test([]job{{code: expr, rterr: rterr}}) } - -// Expression value -func Val(expr string, val interface{}) test { - return test([]job{{code: expr, val: toValue(val)}}) -} - -// Statement runs without error -func Run(stmts string) test { return test([]job{{code: stmts, noval: true}}) } - -// Two statements without error. -// TODO(rsc): Should be possible with Run but the parser -// won't let us do both top-level and non-top-level statements. -func Run2(stmt1, stmt2 string) test { - return test([]job{{code: stmt1, noval: true}, {code: stmt2, noval: true}}) -} - -// Statement runs and test one expression's value -func Val1(stmts string, expr1 string, val1 interface{}) test { - return test([]job{ - {code: stmts, noval: true}, - {code: expr1, val: toValue(val1)}, - }) -} - -// Statement runs and test two expressions' values -func Val2(stmts string, expr1 string, val1 interface{}, expr2 string, val2 interface{}) test { - return test([]job{ - {code: stmts, noval: true}, - {code: expr1, val: toValue(val1)}, - {code: expr2, val: toValue(val2)}, - }) -} - -/* - * Value constructors - */ - -type vstruct []interface{} - -type varray []interface{} - -type vslice struct { - arr varray - len, cap int -} - -func toValue(val interface{}) Value { - switch val := val.(type) { - case bool: - r := boolV(val) - return &r - case uint8: - r := uint8V(val) - return &r - case uint: - r := uintV(val) - return &r - case int: - r := intV(val) - return &r - case *big.Int: - return &idealIntV{val} - case float64: - r := float64V(val) - return &r - case *big.Rat: - return &idealFloatV{val} - case string: - r := stringV(val) - return &r - case vstruct: - elems := make([]Value, len(val)) - for i, e := range val { - elems[i] = toValue(e) - } - r := structV(elems) - return &r - case varray: - elems := make([]Value, len(val)) - for i, e := range val { - elems[i] = toValue(e) - } - r := arrayV(elems) - return &r - case vslice: - return &sliceV{Slice{toValue(val.arr).(ArrayValue), int64(val.len), int64(val.cap)}} - case Func: - return &funcV{val} - } - log.Panicf("toValue(%T) not implemented", val) - panic("unreachable") -} - -/* - * Default test scope - */ - -type testFunc struct{} - -func (*testFunc) NewFrame() *Frame { return &Frame{nil, make([]Value, 2)} } - -func (*testFunc) Call(t *Thread) { - n := t.f.Vars[0].(IntValue).Get(t) - - res := n + 1 - - t.f.Vars[1].(IntValue).Set(t, res) -} - -type oneTwoFunc struct{} - -func (*oneTwoFunc) NewFrame() *Frame { return &Frame{nil, make([]Value, 2)} } - -func (*oneTwoFunc) Call(t *Thread) { - t.f.Vars[0].(IntValue).Set(t, 1) - t.f.Vars[1].(IntValue).Set(t, 2) -} - -type voidFunc struct{} - -func (*voidFunc) NewFrame() *Frame { return &Frame{nil, []Value{}} } - -func (*voidFunc) Call(t *Thread) {} - -func newTestWorld() *World { - w := NewWorld() - - def := func(name string, t Type, val interface{}) { w.DefineVar(name, t, toValue(val)) } - - w.DefineConst("c", IdealIntType, toValue(big.NewInt(1))) - def("i", IntType, 1) - def("i2", IntType, 2) - def("u", UintType, uint(1)) - def("f", Float64Type, 1.0) - def("s", StringType, "abc") - def("t", NewStructType([]StructField{{"a", IntType, false}}), vstruct{1}) - def("ai", NewArrayType(2, IntType), varray{1, 2}) - def("aai", NewArrayType(2, NewArrayType(2, IntType)), varray{varray{1, 2}, varray{3, 4}}) - def("aai2", NewArrayType(2, NewArrayType(2, IntType)), varray{varray{5, 6}, varray{7, 8}}) - def("fn", NewFuncType([]Type{IntType}, false, []Type{IntType}), &testFunc{}) - def("oneTwo", NewFuncType([]Type{}, false, []Type{IntType, IntType}), &oneTwoFunc{}) - def("void", NewFuncType([]Type{}, false, []Type{}), &voidFunc{}) - def("sli", NewSliceType(IntType), vslice{varray{1, 2, 3}, 2, 3}) - - return w -} diff --git a/libgo/go/exp/eval/expr.go b/libgo/go/exp/eval/expr.go deleted file mode 100644 index e65f47617bd..00000000000 --- a/libgo/go/exp/eval/expr.go +++ /dev/null @@ -1,2015 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package eval - -import ( - "big" - "fmt" - "go/ast" - "go/token" - "log" - "strconv" - "strings" - "os" -) - -var ( - idealZero = big.NewInt(0) - idealOne = big.NewInt(1) -) - -// An expr is the result of compiling an expression. It stores the -// type of the expression and its evaluator function. -type expr struct { - *exprInfo - t Type - - // Evaluate this node as the given type. - eval interface{} - - // Map index expressions permit special forms of assignment, - // for which we need to know the Map and key. - evalMapValue func(t *Thread) (Map, interface{}) - - // Evaluate to the "address of" this value; that is, the - // settable Value object. nil for expressions whose address - // cannot be taken. - evalAddr func(t *Thread) Value - - // Execute this expression as a statement. Only expressions - // that are valid expression statements should set this. - exec func(t *Thread) - - // If this expression is a type, this is its compiled type. - // This is only permitted in the function position of a call - // expression. In this case, t should be nil. - valType Type - - // A short string describing this expression for error - // messages. - desc string -} - -// exprInfo stores information needed to compile any expression node. -// Each expr also stores its exprInfo so further expressions can be -// compiled from it. -type exprInfo struct { - *compiler - pos token.Pos -} - -func (a *exprInfo) newExpr(t Type, desc string) *expr { - return &expr{exprInfo: a, t: t, desc: desc} -} - -func (a *exprInfo) diag(format string, args ...interface{}) { - a.diagAt(a.pos, format, args...) -} - -func (a *exprInfo) diagOpType(op token.Token, vt Type) { - a.diag("illegal operand type for '%v' operator\n\t%v", op, vt) -} - -func (a *exprInfo) diagOpTypes(op token.Token, lt Type, rt Type) { - a.diag("illegal operand types for '%v' operator\n\t%v\n\t%v", op, lt, rt) -} - -/* - * Common expression manipulations - */ - -// a.convertTo(t) converts the value of the analyzed expression a, -// which must be a constant, ideal number, to a new analyzed -// expression with a constant value of type t. -// -// TODO(austin) Rename to resolveIdeal or something? -func (a *expr) convertTo(t Type) *expr { - if !a.t.isIdeal() { - log.Panicf("attempted to convert from %v, expected ideal", a.t) - } - - var rat *big.Rat - - // XXX(Spec) The spec says "It is erroneous". - // - // It is an error to assign a value with a non-zero fractional - // part to an integer, or if the assignment would overflow or - // underflow, or in general if the value cannot be represented - // by the type of the variable. - switch a.t { - case IdealFloatType: - rat = a.asIdealFloat()() - if t.isInteger() && !rat.IsInt() { - a.diag("constant %v truncated to integer", rat.FloatString(6)) - return nil - } - case IdealIntType: - i := a.asIdealInt()() - rat = new(big.Rat).SetInt(i) - default: - log.Panicf("unexpected ideal type %v", a.t) - } - - // Check bounds - if t, ok := t.lit().(BoundedType); ok { - if rat.Cmp(t.minVal()) < 0 { - a.diag("constant %v underflows %v", rat.FloatString(6), t) - return nil - } - if rat.Cmp(t.maxVal()) > 0 { - a.diag("constant %v overflows %v", rat.FloatString(6), t) - return nil - } - } - - // Convert rat to type t. - res := a.newExpr(t, a.desc) - switch t := t.lit().(type) { - case *uintType: - n, d := rat.Num(), rat.Denom() - f := new(big.Int).Quo(n, d) - f = f.Abs(f) - v := uint64(f.Int64()) - res.eval = func(*Thread) uint64 { return v } - case *intType: - n, d := rat.Num(), rat.Denom() - f := new(big.Int).Quo(n, d) - v := f.Int64() - res.eval = func(*Thread) int64 { return v } - case *idealIntType: - n, d := rat.Num(), rat.Denom() - f := new(big.Int).Quo(n, d) - res.eval = func() *big.Int { return f } - case *floatType: - n, d := rat.Num(), rat.Denom() - v := float64(n.Int64()) / float64(d.Int64()) - res.eval = func(*Thread) float64 { return v } - case *idealFloatType: - res.eval = func() *big.Rat { return rat } - default: - log.Panicf("cannot convert to type %T", t) - } - - return res -} - -// convertToInt converts this expression to an integer, if possible, -// or produces an error if not. This accepts ideal ints, uints, and -// ints. If max is not -1, produces an error if possible if the value -// exceeds max. If negErr is not "", produces an error if possible if -// the value is negative. -func (a *expr) convertToInt(max int64, negErr string, errOp string) *expr { - switch a.t.lit().(type) { - case *idealIntType: - val := a.asIdealInt()() - if negErr != "" && val.Sign() < 0 { - a.diag("negative %s: %s", negErr, val) - return nil - } - bound := max - if negErr == "slice" { - bound++ - } - if max != -1 && val.Cmp(big.NewInt(bound)) >= 0 { - a.diag("index %s exceeds length %d", val, max) - return nil - } - return a.convertTo(IntType) - - case *uintType: - // Convert to int - na := a.newExpr(IntType, a.desc) - af := a.asUint() - na.eval = func(t *Thread) int64 { return int64(af(t)) } - return na - - case *intType: - // Good as is - return a - } - - a.diag("illegal operand type for %s\n\t%v", errOp, a.t) - return nil -} - -// derefArray returns an expression of array type if the given -// expression is a *array type. Otherwise, returns the given -// expression. -func (a *expr) derefArray() *expr { - if pt, ok := a.t.lit().(*PtrType); ok { - if _, ok := pt.Elem.lit().(*ArrayType); ok { - deref := a.compileStarExpr(a) - if deref == nil { - log.Panicf("failed to dereference *array") - } - return deref - } - } - return a -} - -/* - * Assignments - */ - -// An assignCompiler compiles assignment operations. Anything other -// than short declarations should use the compileAssign wrapper. -// -// There are three valid types of assignment: -// 1) T = T -// Assigning a single expression with single-valued type to a -// single-valued type. -// 2) MT = T, T, ... -// Assigning multiple expressions with single-valued types to a -// multi-valued type. -// 3) MT = MT -// Assigning a single expression with multi-valued type to a -// multi-valued type. -type assignCompiler struct { - *compiler - pos token.Pos - // The RHS expressions. This may include nil's for - // expressions that failed to compile. - rs []*expr - // The (possibly unary) MultiType of the RHS. - rmt *MultiType - // Whether this is an unpack assignment (case 3). - isUnpack bool - // Whether map special assignment forms are allowed. - allowMap bool - // Whether this is a "r, ok = a[x]" assignment. - isMapUnpack bool - // The operation name to use in error messages, such as - // "assignment" or "function call". - errOp string - // The name to use for positions in error messages, such as - // "argument". - errPosName string -} - -// Type check the RHS of an assignment, returning a new assignCompiler -// and indicating if the type check succeeded. This always returns an -// assignCompiler with rmt set, but if type checking fails, slots in -// the MultiType may be nil. If rs contains nil's, type checking will -// fail and these expressions given a nil type. -func (a *compiler) checkAssign(pos token.Pos, rs []*expr, errOp, errPosName string) (*assignCompiler, bool) { - c := &assignCompiler{ - compiler: a, - pos: pos, - rs: rs, - errOp: errOp, - errPosName: errPosName, - } - - // Is this an unpack? - if len(rs) == 1 && rs[0] != nil { - if rmt, isUnpack := rs[0].t.(*MultiType); isUnpack { - c.rmt = rmt - c.isUnpack = true - return c, true - } - } - - // Create MultiType for RHS and check that all RHS expressions - // are single-valued. - rts := make([]Type, len(rs)) - ok := true - for i, r := range rs { - if r == nil { - ok = false - continue - } - - if _, isMT := r.t.(*MultiType); isMT { - r.diag("multi-valued expression not allowed in %s", errOp) - ok = false - continue - } - - rts[i] = r.t - } - - c.rmt = NewMultiType(rts) - return c, ok -} - -func (a *assignCompiler) allowMapForms(nls int) { - a.allowMap = true - - // Update unpacking info if this is r, ok = a[x] - if nls == 2 && len(a.rs) == 1 && a.rs[0] != nil && a.rs[0].evalMapValue != nil { - a.isUnpack = true - a.rmt = NewMultiType([]Type{a.rs[0].t, BoolType}) - a.isMapUnpack = true - } -} - -// compile type checks and compiles an assignment operation, returning -// a function that expects an l-value and the frame in which to -// evaluate the RHS expressions. The l-value must have exactly the -// type given by lt. Returns nil if type checking fails. -func (a *assignCompiler) compile(b *block, lt Type) func(Value, *Thread) { - lmt, isMT := lt.(*MultiType) - rmt, isUnpack := a.rmt, a.isUnpack - - // Create unary MultiType for single LHS - if !isMT { - lmt = NewMultiType([]Type{lt}) - } - - // Check that the assignment count matches - lcount := len(lmt.Elems) - rcount := len(rmt.Elems) - if lcount != rcount { - msg := "not enough" - pos := a.pos - if rcount > lcount { - msg = "too many" - if lcount > 0 { - pos = a.rs[lcount-1].pos - } - } - a.diagAt(pos, "%s %ss for %s\n\t%s\n\t%s", msg, a.errPosName, a.errOp, lt, rmt) - return nil - } - - bad := false - - // If this is an unpack, create a temporary to store the - // multi-value and replace the RHS with expressions to pull - // out values from the temporary. Technically, this is only - // necessary when we need to perform assignment conversions. - var effect func(*Thread) - if isUnpack { - // This leaks a slot, but is definitely safe. - temp := b.DefineTemp(a.rmt) - tempIdx := temp.Index - if tempIdx < 0 { - panic(fmt.Sprintln("tempidx", tempIdx)) - } - if a.isMapUnpack { - rf := a.rs[0].evalMapValue - vt := a.rmt.Elems[0] - effect = func(t *Thread) { - m, k := rf(t) - v := m.Elem(t, k) - found := boolV(true) - if v == nil { - found = boolV(false) - v = vt.Zero() - } - t.f.Vars[tempIdx] = multiV([]Value{v, &found}) - } - } else { - rf := a.rs[0].asMulti() - effect = func(t *Thread) { t.f.Vars[tempIdx] = multiV(rf(t)) } - } - orig := a.rs[0] - a.rs = make([]*expr, len(a.rmt.Elems)) - for i, t := range a.rmt.Elems { - if t.isIdeal() { - log.Panicf("Right side of unpack contains ideal: %s", rmt) - } - a.rs[i] = orig.newExpr(t, orig.desc) - index := i - a.rs[i].genValue(func(t *Thread) Value { return t.f.Vars[tempIdx].(multiV)[index] }) - } - } - // Now len(a.rs) == len(a.rmt) and we've reduced any unpacking - // to multi-assignment. - - // TODO(austin) Deal with assignment special cases. - - // Values of any type may always be assigned to variables of - // compatible static type. - for i, lt := range lmt.Elems { - rt := rmt.Elems[i] - - // When [an ideal is] (used in an expression) assigned - // to a variable or typed constant, the destination - // must be able to represent the assigned value. - if rt.isIdeal() { - a.rs[i] = a.rs[i].convertTo(lmt.Elems[i]) - if a.rs[i] == nil { - bad = true - continue - } - rt = a.rs[i].t - } - - // A pointer p to an array can be assigned to a slice - // variable v with compatible element type if the type - // of p or v is unnamed. - if rpt, ok := rt.lit().(*PtrType); ok { - if at, ok := rpt.Elem.lit().(*ArrayType); ok { - if lst, ok := lt.lit().(*SliceType); ok { - if lst.Elem.compat(at.Elem, false) && (rt.lit() == Type(rt) || lt.lit() == Type(lt)) { - rf := a.rs[i].asPtr() - a.rs[i] = a.rs[i].newExpr(lt, a.rs[i].desc) - len := at.Len - a.rs[i].eval = func(t *Thread) Slice { return Slice{rf(t).(ArrayValue), len, len} } - rt = a.rs[i].t - } - } - } - } - - if !lt.compat(rt, false) { - if len(a.rs) == 1 { - a.rs[0].diag("illegal operand types for %s\n\t%v\n\t%v", a.errOp, lt, rt) - } else { - a.rs[i].diag("illegal operand types in %s %d of %s\n\t%v\n\t%v", a.errPosName, i+1, a.errOp, lt, rt) - } - bad = true - } - } - if bad { - return nil - } - - // Compile - if !isMT { - // Case 1 - return genAssign(lt, a.rs[0]) - } - // Case 2 or 3 - as := make([]func(lv Value, t *Thread), len(a.rs)) - for i, r := range a.rs { - as[i] = genAssign(lmt.Elems[i], r) - } - return func(lv Value, t *Thread) { - if effect != nil { - effect(t) - } - lmv := lv.(multiV) - for i, a := range as { - a(lmv[i], t) - } - } -} - -// compileAssign compiles an assignment operation without the full -// generality of an assignCompiler. See assignCompiler for a -// description of the arguments. -func (a *compiler) compileAssign(pos token.Pos, b *block, lt Type, rs []*expr, errOp, errPosName string) func(Value, *Thread) { - ac, ok := a.checkAssign(pos, rs, errOp, errPosName) - if !ok { - return nil - } - return ac.compile(b, lt) -} - -/* - * Expression compiler - */ - -// An exprCompiler stores information used throughout the compilation -// of a single expression. It does not embed funcCompiler because -// expressions can appear at top level. -type exprCompiler struct { - *compiler - // The block this expression is being compiled in. - block *block - // Whether this expression is used in a constant context. - constant bool -} - -// compile compiles an expression AST. callCtx should be true if this -// AST is in the function position of a function call node; it allows -// the returned expression to be a type or a built-in function (which -// otherwise result in errors). -func (a *exprCompiler) compile(x ast.Expr, callCtx bool) *expr { - ei := &exprInfo{a.compiler, x.Pos()} - - switch x := x.(type) { - // Literals - case *ast.BasicLit: - switch x.Kind { - case token.INT: - return ei.compileIntLit(string(x.Value)) - case token.FLOAT: - return ei.compileFloatLit(string(x.Value)) - case token.CHAR: - return ei.compileCharLit(string(x.Value)) - case token.STRING: - return ei.compileStringLit(string(x.Value)) - default: - log.Panicf("unexpected basic literal type %v", x.Kind) - } - - case *ast.CompositeLit: - goto notimpl - - case *ast.FuncLit: - decl := ei.compileFuncType(a.block, x.Type) - if decl == nil { - // TODO(austin) Try compiling the body, - // perhaps with dummy argument definitions - return nil - } - fn := ei.compileFunc(a.block, decl, x.Body) - if fn == nil { - return nil - } - if a.constant { - a.diagAt(x.Pos(), "function literal used in constant expression") - return nil - } - return ei.compileFuncLit(decl, fn) - - // Types - case *ast.ArrayType: - // TODO(austin) Use a multi-type case - goto typeexpr - - case *ast.ChanType: - goto typeexpr - - case *ast.Ellipsis: - goto typeexpr - - case *ast.FuncType: - goto typeexpr - - case *ast.InterfaceType: - goto typeexpr - - case *ast.MapType: - goto typeexpr - - // Remaining expressions - case *ast.BadExpr: - // Error already reported by parser - a.silentErrors++ - return nil - - case *ast.BinaryExpr: - l, r := a.compile(x.X, false), a.compile(x.Y, false) - if l == nil || r == nil { - return nil - } - return ei.compileBinaryExpr(x.Op, l, r) - - case *ast.CallExpr: - l := a.compile(x.Fun, true) - args := make([]*expr, len(x.Args)) - bad := false - for i, arg := range x.Args { - if i == 0 && l != nil && (l.t == Type(makeType) || l.t == Type(newType)) { - argei := &exprInfo{a.compiler, arg.Pos()} - args[i] = argei.exprFromType(a.compileType(a.block, arg)) - } else { - args[i] = a.compile(arg, false) - } - if args[i] == nil { - bad = true - } - } - if bad || l == nil { - return nil - } - if a.constant { - a.diagAt(x.Pos(), "function call in constant context") - return nil - } - - if l.valType != nil { - a.diagAt(x.Pos(), "type conversions not implemented") - return nil - } else if ft, ok := l.t.(*FuncType); ok && ft.builtin != "" { - return ei.compileBuiltinCallExpr(a.block, ft, args) - } else { - return ei.compileCallExpr(a.block, l, args) - } - - case *ast.Ident: - return ei.compileIdent(a.block, a.constant, callCtx, x.Name) - - case *ast.IndexExpr: - l, r := a.compile(x.X, false), a.compile(x.Index, false) - if l == nil || r == nil { - return nil - } - return ei.compileIndexExpr(l, r) - - case *ast.SliceExpr: - var lo, hi *expr - arr := a.compile(x.X, false) - if x.Low == nil { - // beginning was omitted, so we need to provide it - ei := &exprInfo{a.compiler, x.Pos()} - lo = ei.compileIntLit("0") - } else { - lo = a.compile(x.Low, false) - } - if x.High == nil { - // End was omitted, so we need to compute len(x.X) - ei := &exprInfo{a.compiler, x.Pos()} - hi = ei.compileBuiltinCallExpr(a.block, lenType, []*expr{arr}) - } else { - hi = a.compile(x.High, false) - } - if arr == nil || lo == nil || hi == nil { - return nil - } - return ei.compileSliceExpr(arr, lo, hi) - - case *ast.KeyValueExpr: - goto notimpl - - case *ast.ParenExpr: - return a.compile(x.X, callCtx) - - case *ast.SelectorExpr: - v := a.compile(x.X, false) - if v == nil { - return nil - } - return ei.compileSelectorExpr(v, x.Sel.Name) - - case *ast.StarExpr: - // We pass down our call context because this could be - // a pointer type (and thus a type conversion) - v := a.compile(x.X, callCtx) - if v == nil { - return nil - } - if v.valType != nil { - // Turns out this was a pointer type, not a dereference - return ei.exprFromType(NewPtrType(v.valType)) - } - return ei.compileStarExpr(v) - - case *ast.StructType: - goto notimpl - - case *ast.TypeAssertExpr: - goto notimpl - - case *ast.UnaryExpr: - v := a.compile(x.X, false) - if v == nil { - return nil - } - return ei.compileUnaryExpr(x.Op, v) - } - log.Panicf("unexpected ast node type %T", x) - panic("unreachable") - -typeexpr: - if !callCtx { - a.diagAt(x.Pos(), "type used as expression") - return nil - } - return ei.exprFromType(a.compileType(a.block, x)) - -notimpl: - a.diagAt(x.Pos(), "%T expression node not implemented", x) - return nil -} - -func (a *exprInfo) exprFromType(t Type) *expr { - if t == nil { - return nil - } - expr := a.newExpr(nil, "type") - expr.valType = t - return expr -} - -func (a *exprInfo) compileIdent(b *block, constant bool, callCtx bool, name string) *expr { - bl, level, def := b.Lookup(name) - if def == nil { - a.diag("%s: undefined", name) - return nil - } - switch def := def.(type) { - case *Constant: - expr := a.newExpr(def.Type, "constant") - if ft, ok := def.Type.(*FuncType); ok && ft.builtin != "" { - // XXX(Spec) I don't think anything says that - // built-in functions can't be used as values. - if !callCtx { - a.diag("built-in function %s cannot be used as a value", ft.builtin) - return nil - } - // Otherwise, we leave the evaluators empty - // because this is handled specially - } else { - expr.genConstant(def.Value) - } - return expr - case *Variable: - if constant { - a.diag("variable %s used in constant expression", name) - return nil - } - if bl.global { - return a.compileGlobalVariable(def) - } - return a.compileVariable(level, def) - case Type: - if callCtx { - return a.exprFromType(def) - } - a.diag("type %v used as expression", name) - return nil - } - log.Panicf("name %s has unknown type %T", name, def) - panic("unreachable") -} - -func (a *exprInfo) compileVariable(level int, v *Variable) *expr { - if v.Type == nil { - // Placeholder definition from an earlier error - a.silentErrors++ - return nil - } - expr := a.newExpr(v.Type, "variable") - expr.genIdentOp(level, v.Index) - return expr -} - -func (a *exprInfo) compileGlobalVariable(v *Variable) *expr { - if v.Type == nil { - // Placeholder definition from an earlier error - a.silentErrors++ - return nil - } - if v.Init == nil { - v.Init = v.Type.Zero() - } - expr := a.newExpr(v.Type, "variable") - val := v.Init - expr.genValue(func(t *Thread) Value { return val }) - return expr -} - -func (a *exprInfo) compileIdealInt(i *big.Int, desc string) *expr { - expr := a.newExpr(IdealIntType, desc) - expr.eval = func() *big.Int { return i } - return expr -} - -func (a *exprInfo) compileIntLit(lit string) *expr { - i, _ := new(big.Int).SetString(lit, 0) - return a.compileIdealInt(i, "integer literal") -} - -func (a *exprInfo) compileCharLit(lit string) *expr { - if lit[0] != '\'' { - // Caught by parser - a.silentErrors++ - return nil - } - v, _, tail, err := strconv.UnquoteChar(lit[1:], '\'') - if err != nil || tail != "'" { - // Caught by parser - a.silentErrors++ - return nil - } - return a.compileIdealInt(big.NewInt(int64(v)), "character literal") -} - -func (a *exprInfo) compileFloatLit(lit string) *expr { - f, ok := new(big.Rat).SetString(lit) - if !ok { - log.Panicf("malformed float literal %s at %v passed parser", lit, a.pos) - } - expr := a.newExpr(IdealFloatType, "float literal") - expr.eval = func() *big.Rat { return f } - return expr -} - -func (a *exprInfo) compileString(s string) *expr { - // Ideal strings don't have a named type but they are - // compatible with type string. - - // TODO(austin) Use unnamed string type. - expr := a.newExpr(StringType, "string literal") - expr.eval = func(*Thread) string { return s } - return expr -} - -func (a *exprInfo) compileStringLit(lit string) *expr { - s, err := strconv.Unquote(lit) - if err != nil { - a.diag("illegal string literal, %v", err) - return nil - } - return a.compileString(s) -} - -func (a *exprInfo) compileStringList(list []*expr) *expr { - ss := make([]string, len(list)) - for i, s := range list { - ss[i] = s.asString()(nil) - } - return a.compileString(strings.Join(ss, "")) -} - -func (a *exprInfo) compileFuncLit(decl *FuncDecl, fn func(*Thread) Func) *expr { - expr := a.newExpr(decl.Type, "function literal") - expr.eval = fn - return expr -} - -func (a *exprInfo) compileSelectorExpr(v *expr, name string) *expr { - // mark marks a field that matches the selector name. It - // tracks the best depth found so far and whether more than - // one field has been found at that depth. - bestDepth := -1 - ambig := false - amberr := "" - mark := func(depth int, pathName string) { - switch { - case bestDepth == -1 || depth < bestDepth: - bestDepth = depth - ambig = false - amberr = "" - - case depth == bestDepth: - ambig = true - - default: - log.Panicf("Marked field at depth %d, but already found one at depth %d", depth, bestDepth) - } - amberr += "\n\t" + pathName[1:] - } - - visited := make(map[Type]bool) - - // find recursively searches for the named field, starting at - // type t. If it finds the named field, it returns a function - // which takes an expr that represents a value of type 't' and - // returns an expr that retrieves the named field. We delay - // expr construction to avoid producing lots of useless expr's - // as we search. - // - // TODO(austin) Now that the expression compiler works on - // semantic values instead of AST's, there should be a much - // better way of doing this. - var find func(Type, int, string) func(*expr) *expr - find = func(t Type, depth int, pathName string) func(*expr) *expr { - // Don't bother looking if we've found something shallower - if bestDepth != -1 && bestDepth < depth { - return nil - } - - // Don't check the same type twice and avoid loops - if visited[t] { - return nil - } - visited[t] = true - - // Implicit dereference - deref := false - if ti, ok := t.(*PtrType); ok { - deref = true - t = ti.Elem - } - - // If it's a named type, look for methods - if ti, ok := t.(*NamedType); ok { - _, ok := ti.methods[name] - if ok { - mark(depth, pathName+"."+name) - log.Panic("Methods not implemented") - } - t = ti.Def - } - - // If it's a struct type, check fields and embedded types - var builder func(*expr) *expr - if t, ok := t.(*StructType); ok { - for i, f := range t.Elems { - var sub func(*expr) *expr - switch { - case f.Name == name: - mark(depth, pathName+"."+name) - sub = func(e *expr) *expr { return e } - - case f.Anonymous: - sub = find(f.Type, depth+1, pathName+"."+f.Name) - if sub == nil { - continue - } - - default: - continue - } - - // We found something. Create a - // builder for accessing this field. - ft := f.Type - index := i - builder = func(parent *expr) *expr { - if deref { - parent = a.compileStarExpr(parent) - } - expr := a.newExpr(ft, "selector expression") - pf := parent.asStruct() - evalAddr := func(t *Thread) Value { return pf(t).Field(t, index) } - expr.genValue(evalAddr) - return sub(expr) - } - } - } - - return builder - } - - builder := find(v.t, 0, "") - if builder == nil { - a.diag("type %v has no field or method %s", v.t, name) - return nil - } - if ambig { - a.diag("field %s is ambiguous in type %v%s", name, v.t, amberr) - return nil - } - - return builder(v) -} - -func (a *exprInfo) compileSliceExpr(arr, lo, hi *expr) *expr { - // Type check object - arr = arr.derefArray() - - var at Type - var maxIndex int64 = -1 - - switch lt := arr.t.lit().(type) { - case *ArrayType: - at = NewSliceType(lt.Elem) - maxIndex = lt.Len - - case *SliceType: - at = lt - - case *stringType: - at = lt - - default: - a.diag("cannot slice %v", arr.t) - return nil - } - - // Type check index and convert to int - // XXX(Spec) It's unclear if ideal floats with no - // fractional part are allowed here. 6g allows it. I - // believe that's wrong. - lo = lo.convertToInt(maxIndex, "slice", "slice") - hi = hi.convertToInt(maxIndex, "slice", "slice") - if lo == nil || hi == nil { - return nil - } - - expr := a.newExpr(at, "slice expression") - - // Compile - lof := lo.asInt() - hif := hi.asInt() - switch lt := arr.t.lit().(type) { - case *ArrayType: - arrf := arr.asArray() - bound := lt.Len - expr.eval = func(t *Thread) Slice { - arr, lo, hi := arrf(t), lof(t), hif(t) - if lo > hi || hi > bound || lo < 0 { - t.Abort(SliceError{lo, hi, bound}) - } - return Slice{arr.Sub(lo, bound-lo), hi - lo, bound - lo} - } - - case *SliceType: - arrf := arr.asSlice() - expr.eval = func(t *Thread) Slice { - arr, lo, hi := arrf(t), lof(t), hif(t) - if lo > hi || hi > arr.Cap || lo < 0 { - t.Abort(SliceError{lo, hi, arr.Cap}) - } - return Slice{arr.Base.Sub(lo, arr.Cap-lo), hi - lo, arr.Cap - lo} - } - - case *stringType: - arrf := arr.asString() - // TODO(austin) This pulls over the whole string in a - // remote setting, instead of creating a substring backed - // by remote memory. - expr.eval = func(t *Thread) string { - arr, lo, hi := arrf(t), lof(t), hif(t) - if lo > hi || hi > int64(len(arr)) || lo < 0 { - t.Abort(SliceError{lo, hi, int64(len(arr))}) - } - return arr[lo:hi] - } - - default: - log.Panicf("unexpected left operand type %T", arr.t.lit()) - } - - return expr -} - -func (a *exprInfo) compileIndexExpr(l, r *expr) *expr { - // Type check object - l = l.derefArray() - - var at Type - intIndex := false - var maxIndex int64 = -1 - - switch lt := l.t.lit().(type) { - case *ArrayType: - at = lt.Elem - intIndex = true - maxIndex = lt.Len - - case *SliceType: - at = lt.Elem - intIndex = true - - case *stringType: - at = Uint8Type - intIndex = true - - case *MapType: - at = lt.Elem - if r.t.isIdeal() { - r = r.convertTo(lt.Key) - if r == nil { - return nil - } - } - if !lt.Key.compat(r.t, false) { - a.diag("cannot use %s as index into %s", r.t, lt) - return nil - } - - default: - a.diag("cannot index into %v", l.t) - return nil - } - - // Type check index and convert to int if necessary - if intIndex { - // XXX(Spec) It's unclear if ideal floats with no - // fractional part are allowed here. 6g allows it. I - // believe that's wrong. - r = r.convertToInt(maxIndex, "index", "index") - if r == nil { - return nil - } - } - - expr := a.newExpr(at, "index expression") - - // Compile - switch lt := l.t.lit().(type) { - case *ArrayType: - lf := l.asArray() - rf := r.asInt() - bound := lt.Len - expr.genValue(func(t *Thread) Value { - l, r := lf(t), rf(t) - if r < 0 || r >= bound { - t.Abort(IndexError{r, bound}) - } - return l.Elem(t, r) - }) - - case *SliceType: - lf := l.asSlice() - rf := r.asInt() - expr.genValue(func(t *Thread) Value { - l, r := lf(t), rf(t) - if l.Base == nil { - t.Abort(NilPointerError{}) - } - if r < 0 || r >= l.Len { - t.Abort(IndexError{r, l.Len}) - } - return l.Base.Elem(t, r) - }) - - case *stringType: - lf := l.asString() - rf := r.asInt() - // TODO(austin) This pulls over the whole string in a - // remote setting, instead of just the one character. - expr.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - if r < 0 || r >= int64(len(l)) { - t.Abort(IndexError{r, int64(len(l))}) - } - return uint64(l[r]) - } - - case *MapType: - lf := l.asMap() - rf := r.asInterface() - expr.genValue(func(t *Thread) Value { - m := lf(t) - k := rf(t) - if m == nil { - t.Abort(NilPointerError{}) - } - e := m.Elem(t, k) - if e == nil { - t.Abort(KeyError{k}) - } - return e - }) - // genValue makes things addressable, but map values - // aren't addressable. - expr.evalAddr = nil - expr.evalMapValue = func(t *Thread) (Map, interface{}) { - // TODO(austin) Key check? nil check? - return lf(t), rf(t) - } - - default: - log.Panicf("unexpected left operand type %T", l.t.lit()) - } - - return expr -} - -func (a *exprInfo) compileCallExpr(b *block, l *expr, as []*expr) *expr { - // TODO(austin) Variadic functions. - - // Type check - - // XXX(Spec) Calling a named function type is okay. I really - // think there needs to be a general discussion of named - // types. A named type creates a new, distinct type, but the - // type of that type is still whatever it's defined to. Thus, - // in "type Foo int", Foo is still an integer type and in - // "type Foo func()", Foo is a function type. - lt, ok := l.t.lit().(*FuncType) - if !ok { - a.diag("cannot call non-function type %v", l.t) - return nil - } - - // The arguments must be single-valued expressions assignment - // compatible with the parameters of F. - // - // XXX(Spec) The spec is wrong. It can also be a single - // multi-valued expression. - nin := len(lt.In) - assign := a.compileAssign(a.pos, b, NewMultiType(lt.In), as, "function call", "argument") - if assign == nil { - return nil - } - - var t Type - nout := len(lt.Out) - switch nout { - case 0: - t = EmptyType - case 1: - t = lt.Out[0] - default: - t = NewMultiType(lt.Out) - } - expr := a.newExpr(t, "function call") - - // Gather argument and out types to initialize frame variables - vts := make([]Type, nin+nout) - copy(vts, lt.In) - copy(vts[nin:], lt.Out) - - // Compile - lf := l.asFunc() - call := func(t *Thread) []Value { - fun := lf(t) - fr := fun.NewFrame() - for i, t := range vts { - fr.Vars[i] = t.Zero() - } - assign(multiV(fr.Vars[0:nin]), t) - oldf := t.f - t.f = fr - fun.Call(t) - t.f = oldf - return fr.Vars[nin : nin+nout] - } - expr.genFuncCall(call) - - return expr -} - -func (a *exprInfo) compileBuiltinCallExpr(b *block, ft *FuncType, as []*expr) *expr { - checkCount := func(min, max int) bool { - if len(as) < min { - a.diag("not enough arguments to %s", ft.builtin) - return false - } else if len(as) > max { - a.diag("too many arguments to %s", ft.builtin) - return false - } - return true - } - - switch ft { - case capType: - if !checkCount(1, 1) { - return nil - } - arg := as[0].derefArray() - expr := a.newExpr(IntType, "function call") - switch t := arg.t.lit().(type) { - case *ArrayType: - // TODO(austin) It would be nice if this could - // be a constant int. - v := t.Len - expr.eval = func(t *Thread) int64 { return v } - - case *SliceType: - vf := arg.asSlice() - expr.eval = func(t *Thread) int64 { return vf(t).Cap } - - //case *ChanType: - - default: - a.diag("illegal argument type for cap function\n\t%v", arg.t) - return nil - } - return expr - - case copyType: - if !checkCount(2, 2) { - return nil - } - src := as[1] - dst := as[0] - if src.t != dst.t { - a.diag("arguments to built-in function 'copy' must have same type\nsrc: %s\ndst: %s\n", src.t, dst.t) - return nil - } - if _, ok := src.t.lit().(*SliceType); !ok { - a.diag("src argument to 'copy' must be a slice (got: %s)", src.t) - return nil - } - if _, ok := dst.t.lit().(*SliceType); !ok { - a.diag("dst argument to 'copy' must be a slice (got: %s)", dst.t) - return nil - } - expr := a.newExpr(IntType, "function call") - srcf := src.asSlice() - dstf := dst.asSlice() - expr.eval = func(t *Thread) int64 { - src, dst := srcf(t), dstf(t) - nelems := src.Len - if nelems > dst.Len { - nelems = dst.Len - } - dst.Base.Sub(0, nelems).Assign(t, src.Base.Sub(0, nelems)) - return nelems - } - return expr - - case lenType: - if !checkCount(1, 1) { - return nil - } - arg := as[0].derefArray() - expr := a.newExpr(IntType, "function call") - switch t := arg.t.lit().(type) { - case *stringType: - vf := arg.asString() - expr.eval = func(t *Thread) int64 { return int64(len(vf(t))) } - - case *ArrayType: - // TODO(austin) It would be nice if this could - // be a constant int. - v := t.Len - expr.eval = func(t *Thread) int64 { return v } - - case *SliceType: - vf := arg.asSlice() - expr.eval = func(t *Thread) int64 { return vf(t).Len } - - case *MapType: - vf := arg.asMap() - expr.eval = func(t *Thread) int64 { - // XXX(Spec) What's the len of an - // uninitialized map? - m := vf(t) - if m == nil { - return 0 - } - return m.Len(t) - } - - //case *ChanType: - - default: - a.diag("illegal argument type for len function\n\t%v", arg.t) - return nil - } - return expr - - case makeType: - if !checkCount(1, 3) { - return nil - } - // XXX(Spec) What are the types of the - // arguments? Do they have to be ints? 6g - // accepts any integral type. - var lenexpr, capexpr *expr - var lenf, capf func(*Thread) int64 - if len(as) > 1 { - lenexpr = as[1].convertToInt(-1, "length", "make function") - if lenexpr == nil { - return nil - } - lenf = lenexpr.asInt() - } - if len(as) > 2 { - capexpr = as[2].convertToInt(-1, "capacity", "make function") - if capexpr == nil { - return nil - } - capf = capexpr.asInt() - } - - switch t := as[0].valType.lit().(type) { - case *SliceType: - // A new, initialized slice value for a given - // element type T is made using the built-in - // function make, which takes a slice type and - // parameters specifying the length and - // optionally the capacity. - if !checkCount(2, 3) { - return nil - } - et := t.Elem - expr := a.newExpr(t, "function call") - expr.eval = func(t *Thread) Slice { - l := lenf(t) - // XXX(Spec) What if len or cap is - // negative? The runtime panics. - if l < 0 { - t.Abort(NegativeLengthError{l}) - } - c := l - if capf != nil { - c = capf(t) - if c < 0 { - t.Abort(NegativeCapacityError{c}) - } - // XXX(Spec) What happens if - // len > cap? The runtime - // sets cap to len. - if l > c { - c = l - } - } - base := arrayV(make([]Value, c)) - for i := int64(0); i < c; i++ { - base[i] = et.Zero() - } - return Slice{&base, l, c} - } - return expr - - case *MapType: - // A new, empty map value is made using the - // built-in function make, which takes the map - // type and an optional capacity hint as - // arguments. - if !checkCount(1, 2) { - return nil - } - expr := a.newExpr(t, "function call") - expr.eval = func(t *Thread) Map { - if lenf == nil { - return make(evalMap) - } - l := lenf(t) - return make(evalMap, l) - } - return expr - - //case *ChanType: - - default: - a.diag("illegal argument type for make function\n\t%v", as[0].valType) - return nil - } - - case closeType, closedType: - a.diag("built-in function %s not implemented", ft.builtin) - return nil - - case newType: - if !checkCount(1, 1) { - return nil - } - - t := as[0].valType - expr := a.newExpr(NewPtrType(t), "new") - expr.eval = func(*Thread) Value { return t.Zero() } - return expr - - case panicType, printType, printlnType: - evals := make([]func(*Thread) interface{}, len(as)) - for i, x := range as { - evals[i] = x.asInterface() - } - spaces := ft == printlnType - newline := ft != printType - printer := func(t *Thread) { - for i, eval := range evals { - if i > 0 && spaces { - print(" ") - } - v := eval(t) - type stringer interface { - String() string - } - switch v1 := v.(type) { - case bool: - print(v1) - case uint64: - print(v1) - case int64: - print(v1) - case float64: - print(v1) - case string: - print(v1) - case stringer: - print(v1.String()) - default: - print("???") - } - } - if newline { - print("\n") - } - } - expr := a.newExpr(EmptyType, "print") - expr.exec = printer - if ft == panicType { - expr.exec = func(t *Thread) { - printer(t) - t.Abort(os.NewError("panic")) - } - } - return expr - } - - log.Panicf("unexpected built-in function '%s'", ft.builtin) - panic("unreachable") -} - -func (a *exprInfo) compileStarExpr(v *expr) *expr { - switch vt := v.t.lit().(type) { - case *PtrType: - expr := a.newExpr(vt.Elem, "indirect expression") - vf := v.asPtr() - expr.genValue(func(t *Thread) Value { - v := vf(t) - if v == nil { - t.Abort(NilPointerError{}) - } - return v - }) - return expr - } - - a.diagOpType(token.MUL, v.t) - return nil -} - -var unaryOpDescs = make(map[token.Token]string) - -func (a *exprInfo) compileUnaryExpr(op token.Token, v *expr) *expr { - // Type check - var t Type - switch op { - case token.ADD, token.SUB: - if !v.t.isInteger() && !v.t.isFloat() { - a.diagOpType(op, v.t) - return nil - } - t = v.t - - case token.NOT: - if !v.t.isBoolean() { - a.diagOpType(op, v.t) - return nil - } - t = BoolType - - case token.XOR: - if !v.t.isInteger() { - a.diagOpType(op, v.t) - return nil - } - t = v.t - - case token.AND: - // The unary prefix address-of operator & generates - // the address of its operand, which must be a - // variable, pointer indirection, field selector, or - // array or slice indexing operation. - if v.evalAddr == nil { - a.diag("cannot take the address of %s", v.desc) - return nil - } - - // TODO(austin) Implement "It is illegal to take the - // address of a function result variable" once I have - // function result variables. - - t = NewPtrType(v.t) - - case token.ARROW: - log.Panicf("Unary op %v not implemented", op) - - default: - log.Panicf("unknown unary operator %v", op) - } - - desc, ok := unaryOpDescs[op] - if !ok { - desc = "unary " + op.String() + " expression" - unaryOpDescs[op] = desc - } - - // Compile - expr := a.newExpr(t, desc) - switch op { - case token.ADD: - // Just compile it out - expr = v - expr.desc = desc - - case token.SUB: - expr.genUnaryOpNeg(v) - - case token.NOT: - expr.genUnaryOpNot(v) - - case token.XOR: - expr.genUnaryOpXor(v) - - case token.AND: - vf := v.evalAddr - expr.eval = func(t *Thread) Value { return vf(t) } - - default: - log.Panicf("Compilation of unary op %v not implemented", op) - } - - return expr -} - -var binOpDescs = make(map[token.Token]string) - -func (a *exprInfo) compileBinaryExpr(op token.Token, l, r *expr) *expr { - // Save the original types of l.t and r.t for error messages. - origlt := l.t - origrt := r.t - - // XXX(Spec) What is the exact definition of a "named type"? - - // XXX(Spec) Arithmetic operators: "Integer types" apparently - // means all types compatible with basic integer types, though - // this is never explained. Likewise for float types, etc. - // This relates to the missing explanation of named types. - - // XXX(Spec) Operators: "If both operands are ideal numbers, - // the conversion is to ideal floats if one of the operands is - // an ideal float (relevant for / and %)." How is that - // relevant only for / and %? If I add an ideal int and an - // ideal float, I get an ideal float. - - if op != token.SHL && op != token.SHR { - // Except in shift expressions, if one operand has - // numeric type and the other operand is an ideal - // number, the ideal number is converted to match the - // type of the other operand. - if (l.t.isInteger() || l.t.isFloat()) && !l.t.isIdeal() && r.t.isIdeal() { - r = r.convertTo(l.t) - } else if (r.t.isInteger() || r.t.isFloat()) && !r.t.isIdeal() && l.t.isIdeal() { - l = l.convertTo(r.t) - } - if l == nil || r == nil { - return nil - } - - // Except in shift expressions, if both operands are - // ideal numbers and one is an ideal float, the other - // is converted to ideal float. - if l.t.isIdeal() && r.t.isIdeal() { - if l.t.isInteger() && r.t.isFloat() { - l = l.convertTo(r.t) - } else if l.t.isFloat() && r.t.isInteger() { - r = r.convertTo(l.t) - } - if l == nil || r == nil { - return nil - } - } - } - - // Useful type predicates - // TODO(austin) CL 33668 mandates identical types except for comparisons. - compat := func() bool { return l.t.compat(r.t, false) } - integers := func() bool { return l.t.isInteger() && r.t.isInteger() } - floats := func() bool { return l.t.isFloat() && r.t.isFloat() } - strings := func() bool { - // TODO(austin) Deal with named types - return l.t == StringType && r.t == StringType - } - booleans := func() bool { return l.t.isBoolean() && r.t.isBoolean() } - - // Type check - var t Type - switch op { - case token.ADD: - if !compat() || (!integers() && !floats() && !strings()) { - a.diagOpTypes(op, origlt, origrt) - return nil - } - t = l.t - - case token.SUB, token.MUL, token.QUO: - if !compat() || (!integers() && !floats()) { - a.diagOpTypes(op, origlt, origrt) - return nil - } - t = l.t - - case token.REM, token.AND, token.OR, token.XOR, token.AND_NOT: - if !compat() || !integers() { - a.diagOpTypes(op, origlt, origrt) - return nil - } - t = l.t - - case token.SHL, token.SHR: - // XXX(Spec) Is it okay for the right operand to be an - // ideal float with no fractional part? "The right - // operand in a shift operation must be always be of - // unsigned integer type or an ideal number that can - // be safely converted into an unsigned integer type - // (§Arithmetic operators)" suggests so and 6g agrees. - - if !l.t.isInteger() || !(r.t.isInteger() || r.t.isIdeal()) { - a.diagOpTypes(op, origlt, origrt) - return nil - } - - // The right operand in a shift operation must be - // always be of unsigned integer type or an ideal - // number that can be safely converted into an - // unsigned integer type. - if r.t.isIdeal() { - r2 := r.convertTo(UintType) - if r2 == nil { - return nil - } - - // If the left operand is not ideal, convert - // the right to not ideal. - if !l.t.isIdeal() { - r = r2 - } - - // If both are ideal, but the right side isn't - // an ideal int, convert it to simplify things. - if l.t.isIdeal() && !r.t.isInteger() { - r = r.convertTo(IdealIntType) - if r == nil { - log.Panicf("conversion to uintType succeeded, but conversion to idealIntType failed") - } - } - } else if _, ok := r.t.lit().(*uintType); !ok { - a.diag("right operand of shift must be unsigned") - return nil - } - - if l.t.isIdeal() && !r.t.isIdeal() { - // XXX(Spec) What is the meaning of "ideal >> - // non-ideal"? Russ says the ideal should be - // converted to an int. 6g propagates the - // type down from assignments as a hint. - - l = l.convertTo(IntType) - if l == nil { - return nil - } - } - - // At this point, we should have one of three cases: - // 1) uint SHIFT uint - // 2) int SHIFT uint - // 3) ideal int SHIFT ideal int - - t = l.t - - case token.LOR, token.LAND: - if !booleans() { - return nil - } - // XXX(Spec) There's no mention of *which* boolean - // type the logical operators return. From poking at - // 6g, it appears to be the named boolean type, NOT - // the type of the left operand, and NOT an unnamed - // boolean type. - - t = BoolType - - case token.ARROW: - // The operands in channel sends differ in type: one - // is always a channel and the other is a variable or - // value of the channel's element type. - log.Panic("Binary op <- not implemented") - t = BoolType - - case token.LSS, token.GTR, token.LEQ, token.GEQ: - // XXX(Spec) It's really unclear what types which - // comparison operators apply to. I feel like the - // text is trying to paint a Venn diagram for me, - // which it's really pretty simple: <, <=, >, >= apply - // only to numeric types and strings. == and != apply - // to everything except arrays and structs, and there - // are some restrictions on when it applies to slices. - - if !compat() || (!integers() && !floats() && !strings()) { - a.diagOpTypes(op, origlt, origrt) - return nil - } - t = BoolType - - case token.EQL, token.NEQ: - // XXX(Spec) The rules for type checking comparison - // operators are spread across three places that all - // partially overlap with each other: the Comparison - // Compatibility section, the Operators section, and - // the Comparison Operators section. The Operators - // section should just say that operators require - // identical types (as it does currently) except that - // there a few special cases for comparison, which are - // described in section X. Currently it includes just - // one of the four special cases. The Comparison - // Compatibility section and the Comparison Operators - // section should either be merged, or at least the - // Comparison Compatibility section should be - // exclusively about type checking and the Comparison - // Operators section should be exclusively about - // semantics. - - // XXX(Spec) Comparison operators: "All comparison - // operators apply to basic types except bools." This - // is very difficult to parse. It's explained much - // better in the Comparison Compatibility section. - - // XXX(Spec) Comparison compatibility: "Function - // values are equal if they refer to the same - // function." is rather vague. It should probably be - // similar to the way the rule for map values is - // written: Function values are equal if they were - // created by the same execution of a function literal - // or refer to the same function declaration. This is - // *almost* but not quite waht 6g implements. If a - // function literals does not capture any variables, - // then multiple executions of it will result in the - // same closure. Russ says he'll change that. - - // TODO(austin) Deal with remaining special cases - - if !compat() { - a.diagOpTypes(op, origlt, origrt) - return nil - } - // Arrays and structs may not be compared to anything. - switch l.t.(type) { - case *ArrayType, *StructType: - a.diagOpTypes(op, origlt, origrt) - return nil - } - t = BoolType - - default: - log.Panicf("unknown binary operator %v", op) - } - - desc, ok := binOpDescs[op] - if !ok { - desc = op.String() + " expression" - binOpDescs[op] = desc - } - - // Check for ideal divide by zero - switch op { - case token.QUO, token.REM: - if r.t.isIdeal() { - if (r.t.isInteger() && r.asIdealInt()().Sign() == 0) || - (r.t.isFloat() && r.asIdealFloat()().Sign() == 0) { - a.diag("divide by zero") - return nil - } - } - } - - // Compile - expr := a.newExpr(t, desc) - switch op { - case token.ADD: - expr.genBinOpAdd(l, r) - - case token.SUB: - expr.genBinOpSub(l, r) - - case token.MUL: - expr.genBinOpMul(l, r) - - case token.QUO: - expr.genBinOpQuo(l, r) - - case token.REM: - expr.genBinOpRem(l, r) - - case token.AND: - expr.genBinOpAnd(l, r) - - case token.OR: - expr.genBinOpOr(l, r) - - case token.XOR: - expr.genBinOpXor(l, r) - - case token.AND_NOT: - expr.genBinOpAndNot(l, r) - - case token.SHL: - if l.t.isIdeal() { - lv := l.asIdealInt()() - rv := r.asIdealInt()() - const maxShift = 99999 - if rv.Cmp(big.NewInt(maxShift)) > 0 { - a.diag("left shift by %v; exceeds implementation limit of %v", rv, maxShift) - expr.t = nil - return nil - } - val := new(big.Int).Lsh(lv, uint(rv.Int64())) - expr.eval = func() *big.Int { return val } - } else { - expr.genBinOpShl(l, r) - } - - case token.SHR: - if l.t.isIdeal() { - lv := l.asIdealInt()() - rv := r.asIdealInt()() - val := new(big.Int).Rsh(lv, uint(rv.Int64())) - expr.eval = func() *big.Int { return val } - } else { - expr.genBinOpShr(l, r) - } - - case token.LSS: - expr.genBinOpLss(l, r) - - case token.GTR: - expr.genBinOpGtr(l, r) - - case token.LEQ: - expr.genBinOpLeq(l, r) - - case token.GEQ: - expr.genBinOpGeq(l, r) - - case token.EQL: - expr.genBinOpEql(l, r) - - case token.NEQ: - expr.genBinOpNeq(l, r) - - case token.LAND: - expr.genBinOpLogAnd(l, r) - - case token.LOR: - expr.genBinOpLogOr(l, r) - - default: - log.Panicf("Compilation of binary op %v not implemented", op) - } - - return expr -} - -// TODO(austin) This is a hack to eliminate a circular dependency -// between type.go and expr.go -func (a *compiler) compileArrayLen(b *block, expr ast.Expr) (int64, bool) { - lenExpr := a.compileExpr(b, true, expr) - if lenExpr == nil { - return 0, false - } - - // XXX(Spec) Are ideal floats with no fractional part okay? - if lenExpr.t.isIdeal() { - lenExpr = lenExpr.convertTo(IntType) - if lenExpr == nil { - return 0, false - } - } - - if !lenExpr.t.isInteger() { - a.diagAt(expr.Pos(), "array size must be an integer") - return 0, false - } - - switch lenExpr.t.lit().(type) { - case *intType: - return lenExpr.asInt()(nil), true - case *uintType: - return int64(lenExpr.asUint()(nil)), true - } - log.Panicf("unexpected integer type %T", lenExpr.t) - return 0, false -} - -func (a *compiler) compileExpr(b *block, constant bool, expr ast.Expr) *expr { - ec := &exprCompiler{a, b, constant} - nerr := a.numError() - e := ec.compile(expr, false) - if e == nil && nerr == a.numError() { - log.Panicf("expression compilation failed without reporting errors") - } - return e -} - -// extractEffect separates out any effects that the expression may -// have, returning a function that will perform those effects and a -// new exprCompiler that is guaranteed to be side-effect free. These -// are the moral equivalents of "temp := expr" and "temp" (or "temp := -// &expr" and "*temp" for addressable exprs). Because this creates a -// temporary variable, the caller should create a temporary block for -// the compilation of this expression and the evaluation of the -// results. -func (a *expr) extractEffect(b *block, errOp string) (func(*Thread), *expr) { - // Create "&a" if a is addressable - rhs := a - if a.evalAddr != nil { - rhs = a.compileUnaryExpr(token.AND, rhs) - } - - // Create temp - ac, ok := a.checkAssign(a.pos, []*expr{rhs}, errOp, "") - if !ok { - return nil, nil - } - if len(ac.rmt.Elems) != 1 { - a.diag("multi-valued expression not allowed in %s", errOp) - return nil, nil - } - tempType := ac.rmt.Elems[0] - if tempType.isIdeal() { - // It's too bad we have to duplicate this rule. - switch { - case tempType.isInteger(): - tempType = IntType - case tempType.isFloat(): - tempType = Float64Type - default: - log.Panicf("unexpected ideal type %v", tempType) - } - } - temp := b.DefineTemp(tempType) - tempIdx := temp.Index - - // Create "temp := rhs" - assign := ac.compile(b, tempType) - if assign == nil { - log.Panicf("compileAssign type check failed") - } - - effect := func(t *Thread) { - tempVal := tempType.Zero() - t.f.Vars[tempIdx] = tempVal - assign(tempVal, t) - } - - // Generate "temp" or "*temp" - getTemp := a.compileVariable(0, temp) - if a.evalAddr == nil { - return effect, getTemp - } - - deref := a.compileStarExpr(getTemp) - if deref == nil { - return nil, nil - } - return effect, deref -} diff --git a/libgo/go/exp/eval/expr1.go b/libgo/go/exp/eval/expr1.go deleted file mode 100644 index 5d0e5000032..00000000000 --- a/libgo/go/exp/eval/expr1.go +++ /dev/null @@ -1,1874 +0,0 @@ -// This file is machine generated by gen.go. -// 6g gen.go && 6l gen.6 && ./6.out >expr1.go - -package eval - -import ( - "big" - "log" -) - -/* - * "As" functions. These retrieve evaluator functions from an - * expr, panicking if the requested evaluator has the wrong type. - */ -func (a *expr) asBool() func(*Thread) bool { - return a.eval.(func(*Thread) bool) -} -func (a *expr) asUint() func(*Thread) uint64 { - return a.eval.(func(*Thread) uint64) -} -func (a *expr) asInt() func(*Thread) int64 { - return a.eval.(func(*Thread) int64) -} -func (a *expr) asIdealInt() func() *big.Int { - return a.eval.(func() *big.Int) -} -func (a *expr) asFloat() func(*Thread) float64 { - return a.eval.(func(*Thread) float64) -} -func (a *expr) asIdealFloat() func() *big.Rat { - return a.eval.(func() *big.Rat) -} -func (a *expr) asString() func(*Thread) string { - return a.eval.(func(*Thread) string) -} -func (a *expr) asArray() func(*Thread) ArrayValue { - return a.eval.(func(*Thread) ArrayValue) -} -func (a *expr) asStruct() func(*Thread) StructValue { - return a.eval.(func(*Thread) StructValue) -} -func (a *expr) asPtr() func(*Thread) Value { - return a.eval.(func(*Thread) Value) -} -func (a *expr) asFunc() func(*Thread) Func { - return a.eval.(func(*Thread) Func) -} -func (a *expr) asSlice() func(*Thread) Slice { - return a.eval.(func(*Thread) Slice) -} -func (a *expr) asMap() func(*Thread) Map { - return a.eval.(func(*Thread) Map) -} -func (a *expr) asMulti() func(*Thread) []Value { - return a.eval.(func(*Thread) []Value) -} - -func (a *expr) asInterface() func(*Thread) interface{} { - switch sf := a.eval.(type) { - case func(t *Thread) bool: - return func(t *Thread) interface{} { return sf(t) } - case func(t *Thread) uint64: - return func(t *Thread) interface{} { return sf(t) } - case func(t *Thread) int64: - return func(t *Thread) interface{} { return sf(t) } - case func() *big.Int: - return func(*Thread) interface{} { return sf() } - case func(t *Thread) float64: - return func(t *Thread) interface{} { return sf(t) } - case func() *big.Rat: - return func(*Thread) interface{} { return sf() } - case func(t *Thread) string: - return func(t *Thread) interface{} { return sf(t) } - case func(t *Thread) ArrayValue: - return func(t *Thread) interface{} { return sf(t) } - case func(t *Thread) StructValue: - return func(t *Thread) interface{} { return sf(t) } - case func(t *Thread) Value: - return func(t *Thread) interface{} { return sf(t) } - case func(t *Thread) Func: - return func(t *Thread) interface{} { return sf(t) } - case func(t *Thread) Slice: - return func(t *Thread) interface{} { return sf(t) } - case func(t *Thread) Map: - return func(t *Thread) interface{} { return sf(t) } - default: - log.Panicf("unexpected expression node type %T at %v", a.eval, a.pos) - } - panic("fail") -} - -/* - * Operator generators. - */ - -func (a *expr) genConstant(v Value) { - switch a.t.lit().(type) { - case *boolType: - a.eval = func(t *Thread) bool { return v.(BoolValue).Get(t) } - case *uintType: - a.eval = func(t *Thread) uint64 { return v.(UintValue).Get(t) } - case *intType: - a.eval = func(t *Thread) int64 { return v.(IntValue).Get(t) } - case *idealIntType: - val := v.(IdealIntValue).Get() - a.eval = func() *big.Int { return val } - case *floatType: - a.eval = func(t *Thread) float64 { return v.(FloatValue).Get(t) } - case *idealFloatType: - val := v.(IdealFloatValue).Get() - a.eval = func() *big.Rat { return val } - case *stringType: - a.eval = func(t *Thread) string { return v.(StringValue).Get(t) } - case *ArrayType: - a.eval = func(t *Thread) ArrayValue { return v.(ArrayValue).Get(t) } - case *StructType: - a.eval = func(t *Thread) StructValue { return v.(StructValue).Get(t) } - case *PtrType: - a.eval = func(t *Thread) Value { return v.(PtrValue).Get(t) } - case *FuncType: - a.eval = func(t *Thread) Func { return v.(FuncValue).Get(t) } - case *SliceType: - a.eval = func(t *Thread) Slice { return v.(SliceValue).Get(t) } - case *MapType: - a.eval = func(t *Thread) Map { return v.(MapValue).Get(t) } - default: - log.Panicf("unexpected constant type %v at %v", a.t, a.pos) - } -} - -func (a *expr) genIdentOp(level, index int) { - a.evalAddr = func(t *Thread) Value { return t.f.Get(level, index) } - switch a.t.lit().(type) { - case *boolType: - a.eval = func(t *Thread) bool { return t.f.Get(level, index).(BoolValue).Get(t) } - case *uintType: - a.eval = func(t *Thread) uint64 { return t.f.Get(level, index).(UintValue).Get(t) } - case *intType: - a.eval = func(t *Thread) int64 { return t.f.Get(level, index).(IntValue).Get(t) } - case *floatType: - a.eval = func(t *Thread) float64 { return t.f.Get(level, index).(FloatValue).Get(t) } - case *stringType: - a.eval = func(t *Thread) string { return t.f.Get(level, index).(StringValue).Get(t) } - case *ArrayType: - a.eval = func(t *Thread) ArrayValue { return t.f.Get(level, index).(ArrayValue).Get(t) } - case *StructType: - a.eval = func(t *Thread) StructValue { return t.f.Get(level, index).(StructValue).Get(t) } - case *PtrType: - a.eval = func(t *Thread) Value { return t.f.Get(level, index).(PtrValue).Get(t) } - case *FuncType: - a.eval = func(t *Thread) Func { return t.f.Get(level, index).(FuncValue).Get(t) } - case *SliceType: - a.eval = func(t *Thread) Slice { return t.f.Get(level, index).(SliceValue).Get(t) } - case *MapType: - a.eval = func(t *Thread) Map { return t.f.Get(level, index).(MapValue).Get(t) } - default: - log.Panicf("unexpected identifier type %v at %v", a.t, a.pos) - } -} - -func (a *expr) genFuncCall(call func(t *Thread) []Value) { - a.exec = func(t *Thread) { call(t) } - switch a.t.lit().(type) { - case *boolType: - a.eval = func(t *Thread) bool { return call(t)[0].(BoolValue).Get(t) } - case *uintType: - a.eval = func(t *Thread) uint64 { return call(t)[0].(UintValue).Get(t) } - case *intType: - a.eval = func(t *Thread) int64 { return call(t)[0].(IntValue).Get(t) } - case *floatType: - a.eval = func(t *Thread) float64 { return call(t)[0].(FloatValue).Get(t) } - case *stringType: - a.eval = func(t *Thread) string { return call(t)[0].(StringValue).Get(t) } - case *ArrayType: - a.eval = func(t *Thread) ArrayValue { return call(t)[0].(ArrayValue).Get(t) } - case *StructType: - a.eval = func(t *Thread) StructValue { return call(t)[0].(StructValue).Get(t) } - case *PtrType: - a.eval = func(t *Thread) Value { return call(t)[0].(PtrValue).Get(t) } - case *FuncType: - a.eval = func(t *Thread) Func { return call(t)[0].(FuncValue).Get(t) } - case *SliceType: - a.eval = func(t *Thread) Slice { return call(t)[0].(SliceValue).Get(t) } - case *MapType: - a.eval = func(t *Thread) Map { return call(t)[0].(MapValue).Get(t) } - case *MultiType: - a.eval = func(t *Thread) []Value { return call(t) } - default: - log.Panicf("unexpected result type %v at %v", a.t, a.pos) - } -} - -func (a *expr) genValue(vf func(*Thread) Value) { - a.evalAddr = vf - switch a.t.lit().(type) { - case *boolType: - a.eval = func(t *Thread) bool { return vf(t).(BoolValue).Get(t) } - case *uintType: - a.eval = func(t *Thread) uint64 { return vf(t).(UintValue).Get(t) } - case *intType: - a.eval = func(t *Thread) int64 { return vf(t).(IntValue).Get(t) } - case *floatType: - a.eval = func(t *Thread) float64 { return vf(t).(FloatValue).Get(t) } - case *stringType: - a.eval = func(t *Thread) string { return vf(t).(StringValue).Get(t) } - case *ArrayType: - a.eval = func(t *Thread) ArrayValue { return vf(t).(ArrayValue).Get(t) } - case *StructType: - a.eval = func(t *Thread) StructValue { return vf(t).(StructValue).Get(t) } - case *PtrType: - a.eval = func(t *Thread) Value { return vf(t).(PtrValue).Get(t) } - case *FuncType: - a.eval = func(t *Thread) Func { return vf(t).(FuncValue).Get(t) } - case *SliceType: - a.eval = func(t *Thread) Slice { return vf(t).(SliceValue).Get(t) } - case *MapType: - a.eval = func(t *Thread) Map { return vf(t).(MapValue).Get(t) } - default: - log.Panicf("unexpected result type %v at %v", a.t, a.pos) - } -} - -func (a *expr) genUnaryOpNeg(v *expr) { - switch a.t.lit().(type) { - case *uintType: - vf := v.asUint() - a.eval = func(t *Thread) uint64 { v := vf(t); return -v } - case *intType: - vf := v.asInt() - a.eval = func(t *Thread) int64 { v := vf(t); return -v } - case *idealIntType: - val := v.asIdealInt()() - val.Neg(val) - a.eval = func() *big.Int { return val } - case *floatType: - vf := v.asFloat() - a.eval = func(t *Thread) float64 { v := vf(t); return -v } - case *idealFloatType: - val := v.asIdealFloat()() - val.Neg(val) - a.eval = func() *big.Rat { return val } - default: - log.Panicf("unexpected type %v at %v", a.t, a.pos) - } -} - -func (a *expr) genUnaryOpNot(v *expr) { - switch a.t.lit().(type) { - case *boolType: - vf := v.asBool() - a.eval = func(t *Thread) bool { v := vf(t); return !v } - default: - log.Panicf("unexpected type %v at %v", a.t, a.pos) - } -} - -func (a *expr) genUnaryOpXor(v *expr) { - switch a.t.lit().(type) { - case *uintType: - vf := v.asUint() - a.eval = func(t *Thread) uint64 { v := vf(t); return ^v } - case *intType: - vf := v.asInt() - a.eval = func(t *Thread) int64 { v := vf(t); return ^v } - case *idealIntType: - val := v.asIdealInt()() - val.Not(val) - a.eval = func() *big.Int { return val } - default: - log.Panicf("unexpected type %v at %v", a.t, a.pos) - } -} - -func (a *expr) genBinOpLogAnd(l, r *expr) { - lf := l.asBool() - rf := r.asBool() - a.eval = func(t *Thread) bool { return lf(t) && rf(t) } -} - -func (a *expr) genBinOpLogOr(l, r *expr) { - lf := l.asBool() - rf := r.asBool() - a.eval = func(t *Thread) bool { return lf(t) || rf(t) } -} - -func (a *expr) genBinOpAdd(l, r *expr) { - switch t := l.t.lit().(type) { - case *uintType: - lf := l.asUint() - rf := r.asUint() - switch t.Bits { - case 8: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l + r - return uint64(uint8(ret)) - } - case 16: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l + r - return uint64(uint16(ret)) - } - case 32: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l + r - return uint64(uint32(ret)) - } - case 64: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l + r - return uint64(uint64(ret)) - } - case 0: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l + r - return uint64(uint(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - case *intType: - lf := l.asInt() - rf := r.asInt() - switch t.Bits { - case 8: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l + r - return int64(int8(ret)) - } - case 16: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l + r - return int64(int16(ret)) - } - case 32: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l + r - return int64(int32(ret)) - } - case 64: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l + r - return int64(int64(ret)) - } - case 0: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l + r - return int64(int(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - case *idealIntType: - l := l.asIdealInt()() - r := r.asIdealInt()() - val := l.Add(l, r) - a.eval = func() *big.Int { return val } - case *floatType: - lf := l.asFloat() - rf := r.asFloat() - switch t.Bits { - case 32: - a.eval = func(t *Thread) float64 { - l, r := lf(t), rf(t) - var ret float64 - ret = l + r - return float64(float32(ret)) - } - case 64: - a.eval = func(t *Thread) float64 { - l, r := lf(t), rf(t) - var ret float64 - ret = l + r - return float64(float64(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - case *idealFloatType: - l := l.asIdealFloat()() - r := r.asIdealFloat()() - val := l.Add(l, r) - a.eval = func() *big.Rat { return val } - case *stringType: - lf := l.asString() - rf := r.asString() - a.eval = func(t *Thread) string { - l, r := lf(t), rf(t) - return l + r - } - default: - log.Panicf("unexpected type %v at %v", l.t, a.pos) - } -} - -func (a *expr) genBinOpSub(l, r *expr) { - switch t := l.t.lit().(type) { - case *uintType: - lf := l.asUint() - rf := r.asUint() - switch t.Bits { - case 8: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l - r - return uint64(uint8(ret)) - } - case 16: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l - r - return uint64(uint16(ret)) - } - case 32: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l - r - return uint64(uint32(ret)) - } - case 64: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l - r - return uint64(uint64(ret)) - } - case 0: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l - r - return uint64(uint(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - case *intType: - lf := l.asInt() - rf := r.asInt() - switch t.Bits { - case 8: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l - r - return int64(int8(ret)) - } - case 16: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l - r - return int64(int16(ret)) - } - case 32: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l - r - return int64(int32(ret)) - } - case 64: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l - r - return int64(int64(ret)) - } - case 0: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l - r - return int64(int(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - case *idealIntType: - l := l.asIdealInt()() - r := r.asIdealInt()() - val := l.Sub(l, r) - a.eval = func() *big.Int { return val } - case *floatType: - lf := l.asFloat() - rf := r.asFloat() - switch t.Bits { - case 32: - a.eval = func(t *Thread) float64 { - l, r := lf(t), rf(t) - var ret float64 - ret = l - r - return float64(float32(ret)) - } - case 64: - a.eval = func(t *Thread) float64 { - l, r := lf(t), rf(t) - var ret float64 - ret = l - r - return float64(float64(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - case *idealFloatType: - l := l.asIdealFloat()() - r := r.asIdealFloat()() - val := l.Sub(l, r) - a.eval = func() *big.Rat { return val } - default: - log.Panicf("unexpected type %v at %v", l.t, a.pos) - } -} - -func (a *expr) genBinOpMul(l, r *expr) { - switch t := l.t.lit().(type) { - case *uintType: - lf := l.asUint() - rf := r.asUint() - switch t.Bits { - case 8: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l * r - return uint64(uint8(ret)) - } - case 16: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l * r - return uint64(uint16(ret)) - } - case 32: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l * r - return uint64(uint32(ret)) - } - case 64: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l * r - return uint64(uint64(ret)) - } - case 0: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l * r - return uint64(uint(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - case *intType: - lf := l.asInt() - rf := r.asInt() - switch t.Bits { - case 8: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l * r - return int64(int8(ret)) - } - case 16: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l * r - return int64(int16(ret)) - } - case 32: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l * r - return int64(int32(ret)) - } - case 64: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l * r - return int64(int64(ret)) - } - case 0: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l * r - return int64(int(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - case *idealIntType: - l := l.asIdealInt()() - r := r.asIdealInt()() - val := l.Mul(l, r) - a.eval = func() *big.Int { return val } - case *floatType: - lf := l.asFloat() - rf := r.asFloat() - switch t.Bits { - case 32: - a.eval = func(t *Thread) float64 { - l, r := lf(t), rf(t) - var ret float64 - ret = l * r - return float64(float32(ret)) - } - case 64: - a.eval = func(t *Thread) float64 { - l, r := lf(t), rf(t) - var ret float64 - ret = l * r - return float64(float64(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - case *idealFloatType: - l := l.asIdealFloat()() - r := r.asIdealFloat()() - val := l.Mul(l, r) - a.eval = func() *big.Rat { return val } - default: - log.Panicf("unexpected type %v at %v", l.t, a.pos) - } -} - -func (a *expr) genBinOpQuo(l, r *expr) { - switch t := l.t.lit().(type) { - case *uintType: - lf := l.asUint() - rf := r.asUint() - switch t.Bits { - case 8: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - if r == 0 { - t.Abort(DivByZeroError{}) - } - ret = l / r - return uint64(uint8(ret)) - } - case 16: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - if r == 0 { - t.Abort(DivByZeroError{}) - } - ret = l / r - return uint64(uint16(ret)) - } - case 32: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - if r == 0 { - t.Abort(DivByZeroError{}) - } - ret = l / r - return uint64(uint32(ret)) - } - case 64: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - if r == 0 { - t.Abort(DivByZeroError{}) - } - ret = l / r - return uint64(uint64(ret)) - } - case 0: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - if r == 0 { - t.Abort(DivByZeroError{}) - } - ret = l / r - return uint64(uint(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - case *intType: - lf := l.asInt() - rf := r.asInt() - switch t.Bits { - case 8: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - if r == 0 { - t.Abort(DivByZeroError{}) - } - ret = l / r - return int64(int8(ret)) - } - case 16: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - if r == 0 { - t.Abort(DivByZeroError{}) - } - ret = l / r - return int64(int16(ret)) - } - case 32: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - if r == 0 { - t.Abort(DivByZeroError{}) - } - ret = l / r - return int64(int32(ret)) - } - case 64: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - if r == 0 { - t.Abort(DivByZeroError{}) - } - ret = l / r - return int64(int64(ret)) - } - case 0: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - if r == 0 { - t.Abort(DivByZeroError{}) - } - ret = l / r - return int64(int(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - case *idealIntType: - l := l.asIdealInt()() - r := r.asIdealInt()() - val := l.Quo(l, r) - a.eval = func() *big.Int { return val } - case *floatType: - lf := l.asFloat() - rf := r.asFloat() - switch t.Bits { - case 32: - a.eval = func(t *Thread) float64 { - l, r := lf(t), rf(t) - var ret float64 - if r == 0 { - t.Abort(DivByZeroError{}) - } - ret = l / r - return float64(float32(ret)) - } - case 64: - a.eval = func(t *Thread) float64 { - l, r := lf(t), rf(t) - var ret float64 - if r == 0 { - t.Abort(DivByZeroError{}) - } - ret = l / r - return float64(float64(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - case *idealFloatType: - l := l.asIdealFloat()() - r := r.asIdealFloat()() - val := l.Quo(l, r) - a.eval = func() *big.Rat { return val } - default: - log.Panicf("unexpected type %v at %v", l.t, a.pos) - } -} - -func (a *expr) genBinOpRem(l, r *expr) { - switch t := l.t.lit().(type) { - case *uintType: - lf := l.asUint() - rf := r.asUint() - switch t.Bits { - case 8: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - if r == 0 { - t.Abort(DivByZeroError{}) - } - ret = l % r - return uint64(uint8(ret)) - } - case 16: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - if r == 0 { - t.Abort(DivByZeroError{}) - } - ret = l % r - return uint64(uint16(ret)) - } - case 32: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - if r == 0 { - t.Abort(DivByZeroError{}) - } - ret = l % r - return uint64(uint32(ret)) - } - case 64: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - if r == 0 { - t.Abort(DivByZeroError{}) - } - ret = l % r - return uint64(uint64(ret)) - } - case 0: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - if r == 0 { - t.Abort(DivByZeroError{}) - } - ret = l % r - return uint64(uint(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - case *intType: - lf := l.asInt() - rf := r.asInt() - switch t.Bits { - case 8: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - if r == 0 { - t.Abort(DivByZeroError{}) - } - ret = l % r - return int64(int8(ret)) - } - case 16: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - if r == 0 { - t.Abort(DivByZeroError{}) - } - ret = l % r - return int64(int16(ret)) - } - case 32: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - if r == 0 { - t.Abort(DivByZeroError{}) - } - ret = l % r - return int64(int32(ret)) - } - case 64: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - if r == 0 { - t.Abort(DivByZeroError{}) - } - ret = l % r - return int64(int64(ret)) - } - case 0: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - if r == 0 { - t.Abort(DivByZeroError{}) - } - ret = l % r - return int64(int(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - case *idealIntType: - l := l.asIdealInt()() - r := r.asIdealInt()() - val := l.Rem(l, r) - a.eval = func() *big.Int { return val } - default: - log.Panicf("unexpected type %v at %v", l.t, a.pos) - } -} - -func (a *expr) genBinOpAnd(l, r *expr) { - switch t := l.t.lit().(type) { - case *uintType: - lf := l.asUint() - rf := r.asUint() - switch t.Bits { - case 8: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l & r - return uint64(uint8(ret)) - } - case 16: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l & r - return uint64(uint16(ret)) - } - case 32: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l & r - return uint64(uint32(ret)) - } - case 64: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l & r - return uint64(uint64(ret)) - } - case 0: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l & r - return uint64(uint(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - case *intType: - lf := l.asInt() - rf := r.asInt() - switch t.Bits { - case 8: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l & r - return int64(int8(ret)) - } - case 16: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l & r - return int64(int16(ret)) - } - case 32: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l & r - return int64(int32(ret)) - } - case 64: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l & r - return int64(int64(ret)) - } - case 0: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l & r - return int64(int(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - case *idealIntType: - l := l.asIdealInt()() - r := r.asIdealInt()() - val := l.And(l, r) - a.eval = func() *big.Int { return val } - default: - log.Panicf("unexpected type %v at %v", l.t, a.pos) - } -} - -func (a *expr) genBinOpOr(l, r *expr) { - switch t := l.t.lit().(type) { - case *uintType: - lf := l.asUint() - rf := r.asUint() - switch t.Bits { - case 8: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l | r - return uint64(uint8(ret)) - } - case 16: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l | r - return uint64(uint16(ret)) - } - case 32: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l | r - return uint64(uint32(ret)) - } - case 64: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l | r - return uint64(uint64(ret)) - } - case 0: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l | r - return uint64(uint(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - case *intType: - lf := l.asInt() - rf := r.asInt() - switch t.Bits { - case 8: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l | r - return int64(int8(ret)) - } - case 16: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l | r - return int64(int16(ret)) - } - case 32: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l | r - return int64(int32(ret)) - } - case 64: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l | r - return int64(int64(ret)) - } - case 0: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l | r - return int64(int(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - case *idealIntType: - l := l.asIdealInt()() - r := r.asIdealInt()() - val := l.Or(l, r) - a.eval = func() *big.Int { return val } - default: - log.Panicf("unexpected type %v at %v", l.t, a.pos) - } -} - -func (a *expr) genBinOpXor(l, r *expr) { - switch t := l.t.lit().(type) { - case *uintType: - lf := l.asUint() - rf := r.asUint() - switch t.Bits { - case 8: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l ^ r - return uint64(uint8(ret)) - } - case 16: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l ^ r - return uint64(uint16(ret)) - } - case 32: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l ^ r - return uint64(uint32(ret)) - } - case 64: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l ^ r - return uint64(uint64(ret)) - } - case 0: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l ^ r - return uint64(uint(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - case *intType: - lf := l.asInt() - rf := r.asInt() - switch t.Bits { - case 8: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l ^ r - return int64(int8(ret)) - } - case 16: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l ^ r - return int64(int16(ret)) - } - case 32: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l ^ r - return int64(int32(ret)) - } - case 64: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l ^ r - return int64(int64(ret)) - } - case 0: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l ^ r - return int64(int(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - case *idealIntType: - l := l.asIdealInt()() - r := r.asIdealInt()() - val := l.Xor(l, r) - a.eval = func() *big.Int { return val } - default: - log.Panicf("unexpected type %v at %v", l.t, a.pos) - } -} - -func (a *expr) genBinOpAndNot(l, r *expr) { - switch t := l.t.lit().(type) { - case *uintType: - lf := l.asUint() - rf := r.asUint() - switch t.Bits { - case 8: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l &^ r - return uint64(uint8(ret)) - } - case 16: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l &^ r - return uint64(uint16(ret)) - } - case 32: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l &^ r - return uint64(uint32(ret)) - } - case 64: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l &^ r - return uint64(uint64(ret)) - } - case 0: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l &^ r - return uint64(uint(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - case *intType: - lf := l.asInt() - rf := r.asInt() - switch t.Bits { - case 8: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l &^ r - return int64(int8(ret)) - } - case 16: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l &^ r - return int64(int16(ret)) - } - case 32: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l &^ r - return int64(int32(ret)) - } - case 64: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l &^ r - return int64(int64(ret)) - } - case 0: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l &^ r - return int64(int(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - case *idealIntType: - l := l.asIdealInt()() - r := r.asIdealInt()() - val := l.AndNot(l, r) - a.eval = func() *big.Int { return val } - default: - log.Panicf("unexpected type %v at %v", l.t, a.pos) - } -} - -func (a *expr) genBinOpShl(l, r *expr) { - switch t := l.t.lit().(type) { - case *uintType: - lf := l.asUint() - rf := r.asUint() - switch t.Bits { - case 8: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l << r - return uint64(uint8(ret)) - } - case 16: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l << r - return uint64(uint16(ret)) - } - case 32: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l << r - return uint64(uint32(ret)) - } - case 64: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l << r - return uint64(uint64(ret)) - } - case 0: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l << r - return uint64(uint(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - case *intType: - lf := l.asInt() - rf := r.asUint() - switch t.Bits { - case 8: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l << r - return int64(int8(ret)) - } - case 16: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l << r - return int64(int16(ret)) - } - case 32: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l << r - return int64(int32(ret)) - } - case 64: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l << r - return int64(int64(ret)) - } - case 0: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l << r - return int64(int(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - default: - log.Panicf("unexpected type %v at %v", l.t, a.pos) - } -} - -func (a *expr) genBinOpShr(l, r *expr) { - switch t := l.t.lit().(type) { - case *uintType: - lf := l.asUint() - rf := r.asUint() - switch t.Bits { - case 8: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l >> r - return uint64(uint8(ret)) - } - case 16: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l >> r - return uint64(uint16(ret)) - } - case 32: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l >> r - return uint64(uint32(ret)) - } - case 64: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l >> r - return uint64(uint64(ret)) - } - case 0: - a.eval = func(t *Thread) uint64 { - l, r := lf(t), rf(t) - var ret uint64 - ret = l >> r - return uint64(uint(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - case *intType: - lf := l.asInt() - rf := r.asUint() - switch t.Bits { - case 8: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l >> r - return int64(int8(ret)) - } - case 16: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l >> r - return int64(int16(ret)) - } - case 32: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l >> r - return int64(int32(ret)) - } - case 64: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l >> r - return int64(int64(ret)) - } - case 0: - a.eval = func(t *Thread) int64 { - l, r := lf(t), rf(t) - var ret int64 - ret = l >> r - return int64(int(ret)) - } - default: - log.Panicf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) - } - default: - log.Panicf("unexpected type %v at %v", l.t, a.pos) - } -} - -func (a *expr) genBinOpLss(l, r *expr) { - switch t := l.t.lit().(type) { - case *uintType: - lf := l.asUint() - rf := r.asUint() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l < r - } - case *intType: - lf := l.asInt() - rf := r.asInt() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l < r - } - case *idealIntType: - l := l.asIdealInt()() - r := r.asIdealInt()() - val := l.Cmp(r) < 0 - a.eval = func(t *Thread) bool { return val } - case *floatType: - lf := l.asFloat() - rf := r.asFloat() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l < r - } - case *idealFloatType: - l := l.asIdealFloat()() - r := r.asIdealFloat()() - val := l.Cmp(r) < 0 - a.eval = func(t *Thread) bool { return val } - case *stringType: - lf := l.asString() - rf := r.asString() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l < r - } - default: - log.Panicf("unexpected type %v at %v", l.t, a.pos) - } -} - -func (a *expr) genBinOpGtr(l, r *expr) { - switch t := l.t.lit().(type) { - case *uintType: - lf := l.asUint() - rf := r.asUint() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l > r - } - case *intType: - lf := l.asInt() - rf := r.asInt() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l > r - } - case *idealIntType: - l := l.asIdealInt()() - r := r.asIdealInt()() - val := l.Cmp(r) > 0 - a.eval = func(t *Thread) bool { return val } - case *floatType: - lf := l.asFloat() - rf := r.asFloat() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l > r - } - case *idealFloatType: - l := l.asIdealFloat()() - r := r.asIdealFloat()() - val := l.Cmp(r) > 0 - a.eval = func(t *Thread) bool { return val } - case *stringType: - lf := l.asString() - rf := r.asString() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l > r - } - default: - log.Panicf("unexpected type %v at %v", l.t, a.pos) - } -} - -func (a *expr) genBinOpLeq(l, r *expr) { - switch t := l.t.lit().(type) { - case *uintType: - lf := l.asUint() - rf := r.asUint() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l <= r - } - case *intType: - lf := l.asInt() - rf := r.asInt() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l <= r - } - case *idealIntType: - l := l.asIdealInt()() - r := r.asIdealInt()() - val := l.Cmp(r) <= 0 - a.eval = func(t *Thread) bool { return val } - case *floatType: - lf := l.asFloat() - rf := r.asFloat() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l <= r - } - case *idealFloatType: - l := l.asIdealFloat()() - r := r.asIdealFloat()() - val := l.Cmp(r) <= 0 - a.eval = func(t *Thread) bool { return val } - case *stringType: - lf := l.asString() - rf := r.asString() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l <= r - } - default: - log.Panicf("unexpected type %v at %v", l.t, a.pos) - } -} - -func (a *expr) genBinOpGeq(l, r *expr) { - switch t := l.t.lit().(type) { - case *uintType: - lf := l.asUint() - rf := r.asUint() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l >= r - } - case *intType: - lf := l.asInt() - rf := r.asInt() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l >= r - } - case *idealIntType: - l := l.asIdealInt()() - r := r.asIdealInt()() - val := l.Cmp(r) >= 0 - a.eval = func(t *Thread) bool { return val } - case *floatType: - lf := l.asFloat() - rf := r.asFloat() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l >= r - } - case *idealFloatType: - l := l.asIdealFloat()() - r := r.asIdealFloat()() - val := l.Cmp(r) >= 0 - a.eval = func(t *Thread) bool { return val } - case *stringType: - lf := l.asString() - rf := r.asString() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l >= r - } - default: - log.Panicf("unexpected type %v at %v", l.t, a.pos) - } -} - -func (a *expr) genBinOpEql(l, r *expr) { - switch t := l.t.lit().(type) { - case *boolType: - lf := l.asBool() - rf := r.asBool() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l == r - } - case *uintType: - lf := l.asUint() - rf := r.asUint() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l == r - } - case *intType: - lf := l.asInt() - rf := r.asInt() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l == r - } - case *idealIntType: - l := l.asIdealInt()() - r := r.asIdealInt()() - val := l.Cmp(r) == 0 - a.eval = func(t *Thread) bool { return val } - case *floatType: - lf := l.asFloat() - rf := r.asFloat() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l == r - } - case *idealFloatType: - l := l.asIdealFloat()() - r := r.asIdealFloat()() - val := l.Cmp(r) == 0 - a.eval = func(t *Thread) bool { return val } - case *stringType: - lf := l.asString() - rf := r.asString() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l == r - } - case *PtrType: - lf := l.asPtr() - rf := r.asPtr() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l == r - } - case *FuncType: - lf := l.asFunc() - rf := r.asFunc() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l == r - } - case *MapType: - lf := l.asMap() - rf := r.asMap() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l == r - } - default: - log.Panicf("unexpected type %v at %v", l.t, a.pos) - } -} - -func (a *expr) genBinOpNeq(l, r *expr) { - switch t := l.t.lit().(type) { - case *boolType: - lf := l.asBool() - rf := r.asBool() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l != r - } - case *uintType: - lf := l.asUint() - rf := r.asUint() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l != r - } - case *intType: - lf := l.asInt() - rf := r.asInt() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l != r - } - case *idealIntType: - l := l.asIdealInt()() - r := r.asIdealInt()() - val := l.Cmp(r) != 0 - a.eval = func(t *Thread) bool { return val } - case *floatType: - lf := l.asFloat() - rf := r.asFloat() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l != r - } - case *idealFloatType: - l := l.asIdealFloat()() - r := r.asIdealFloat()() - val := l.Cmp(r) != 0 - a.eval = func(t *Thread) bool { return val } - case *stringType: - lf := l.asString() - rf := r.asString() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l != r - } - case *PtrType: - lf := l.asPtr() - rf := r.asPtr() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l != r - } - case *FuncType: - lf := l.asFunc() - rf := r.asFunc() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l != r - } - case *MapType: - lf := l.asMap() - rf := r.asMap() - a.eval = func(t *Thread) bool { - l, r := lf(t), rf(t) - return l != r - } - default: - log.Panicf("unexpected type %v at %v", l.t, a.pos) - } -} - -func genAssign(lt Type, r *expr) func(lv Value, t *Thread) { - switch lt.lit().(type) { - case *boolType: - rf := r.asBool() - return func(lv Value, t *Thread) { lv.(BoolValue).Set(t, rf(t)) } - case *uintType: - rf := r.asUint() - return func(lv Value, t *Thread) { lv.(UintValue).Set(t, rf(t)) } - case *intType: - rf := r.asInt() - return func(lv Value, t *Thread) { lv.(IntValue).Set(t, rf(t)) } - case *floatType: - rf := r.asFloat() - return func(lv Value, t *Thread) { lv.(FloatValue).Set(t, rf(t)) } - case *stringType: - rf := r.asString() - return func(lv Value, t *Thread) { lv.(StringValue).Set(t, rf(t)) } - case *ArrayType: - rf := r.asArray() - return func(lv Value, t *Thread) { lv.Assign(t, rf(t)) } - case *StructType: - rf := r.asStruct() - return func(lv Value, t *Thread) { lv.Assign(t, rf(t)) } - case *PtrType: - rf := r.asPtr() - return func(lv Value, t *Thread) { lv.(PtrValue).Set(t, rf(t)) } - case *FuncType: - rf := r.asFunc() - return func(lv Value, t *Thread) { lv.(FuncValue).Set(t, rf(t)) } - case *SliceType: - rf := r.asSlice() - return func(lv Value, t *Thread) { lv.(SliceValue).Set(t, rf(t)) } - case *MapType: - rf := r.asMap() - return func(lv Value, t *Thread) { lv.(MapValue).Set(t, rf(t)) } - default: - log.Panicf("unexpected left operand type %v at %v", lt, r.pos) - } - panic("fail") -} diff --git a/libgo/go/exp/eval/expr_test.go b/libgo/go/exp/eval/expr_test.go deleted file mode 100644 index 0dbce431520..00000000000 --- a/libgo/go/exp/eval/expr_test.go +++ /dev/null @@ -1,355 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package eval - -import ( - "big" - "testing" -) - -var undefined = "undefined" -var typeAsExpr = "type .* used as expression" -var badCharLit = "character literal" -var unknownEscape = "unknown escape sequence" -var opTypes = "illegal (operand|argument) type|cannot index into" -var badAddrOf = "cannot take the address" -var constantTruncated = "constant [^ ]* truncated" -var constantUnderflows = "constant [^ ]* underflows" -var constantOverflows = "constant [^ ]* overflows" -var implLimit = "implementation limit" -var mustBeUnsigned = "must be unsigned" -var divByZero = "divide by zero" - -var hugeInteger = new(big.Int).Lsh(idealOne, 64) - -var exprTests = []test{ - Val("i", 1), - CErr("zzz", undefined), - // TODO(austin) Test variable in constant context - //CErr("t", typeAsExpr), - - Val("'a'", big.NewInt('a')), - Val("'\\uffff'", big.NewInt('\uffff')), - Val("'\\n'", big.NewInt('\n')), - CErr("''+x", badCharLit), - // Produces two parse errors - //CErr("'''", ""), - CErr("'\n'", badCharLit), - CErr("'\\z'", unknownEscape), - CErr("'ab'", badCharLit), - - Val("1.0", big.NewRat(1, 1)), - Val("1.", big.NewRat(1, 1)), - Val(".1", big.NewRat(1, 10)), - Val("1e2", big.NewRat(100, 1)), - - Val("\"abc\"", "abc"), - Val("\"\"", ""), - Val("\"\\n\\\"\"", "\n\""), - CErr("\"\\z\"", unknownEscape), - CErr("\"abc", "string not terminated"), - - Val("(i)", 1), - - Val("ai[0]", 1), - Val("(&ai)[0]", 1), - Val("ai[1]", 2), - Val("ai[i]", 2), - Val("ai[u]", 2), - CErr("ai[f]", opTypes), - CErr("ai[0][0]", opTypes), - CErr("ai[2]", "index 2 exceeds"), - CErr("ai[1+1]", "index 2 exceeds"), - CErr("ai[-1]", "negative index"), - RErr("ai[i+i]", "index 2 exceeds"), - RErr("ai[-i]", "negative index"), - CErr("i[0]", opTypes), - CErr("f[0]", opTypes), - - Val("aai[0][0]", 1), - Val("aai[1][1]", 4), - CErr("aai[2][0]", "index 2 exceeds"), - CErr("aai[0][2]", "index 2 exceeds"), - - Val("sli[0]", 1), - Val("sli[1]", 2), - CErr("sli[-1]", "negative index"), - RErr("sli[-i]", "negative index"), - RErr("sli[2]", "index 2 exceeds"), - - Val("s[0]", uint8('a')), - Val("s[1]", uint8('b')), - CErr("s[-1]", "negative index"), - RErr("s[-i]", "negative index"), - RErr("s[3]", "index 3 exceeds"), - - Val("ai[0:2]", vslice{varray{1, 2}, 2, 2}), - Val("ai[0:1]", vslice{varray{1, 2}, 1, 2}), - Val("ai[0:]", vslice{varray{1, 2}, 2, 2}), - Val("ai[i:]", vslice{varray{2}, 1, 1}), - - Val("sli[0:2]", vslice{varray{1, 2, 3}, 2, 3}), - Val("sli[0:i]", vslice{varray{1, 2, 3}, 1, 3}), - Val("sli[1:]", vslice{varray{2, 3}, 1, 2}), - - CErr("1(2)", "cannot call"), - CErr("fn(1,2)", "too many"), - CErr("fn()", "not enough"), - CErr("fn(true)", opTypes), - CErr("fn(true)", "function call"), - // Single argument functions don't say which argument. - //CErr("fn(true)", "argument 1"), - Val("fn(1)", 2), - Val("fn(1.0)", 2), - CErr("fn(1.5)", constantTruncated), - Val("fn(i)", 2), - CErr("fn(u)", opTypes), - - CErr("void()+2", opTypes), - CErr("oneTwo()+2", opTypes), - - Val("cap(ai)", 2), - Val("cap(&ai)", 2), - Val("cap(aai)", 2), - Val("cap(sli)", 3), - CErr("cap(0)", opTypes), - CErr("cap(i)", opTypes), - CErr("cap(s)", opTypes), - - Val("len(s)", 3), - Val("len(ai)", 2), - Val("len(&ai)", 2), - Val("len(ai[0:])", 2), - Val("len(ai[1:])", 1), - Val("len(ai[2:])", 0), - Val("len(aai)", 2), - Val("len(sli)", 2), - Val("len(sli[0:])", 2), - Val("len(sli[1:])", 1), - Val("len(sli[2:])", 0), - // TODO(austin) Test len of map - CErr("len(0)", opTypes), - CErr("len(i)", opTypes), - - CErr("*i", opTypes), - Val("*&i", 1), - Val("*&(i)", 1), - CErr("&1", badAddrOf), - CErr("&c", badAddrOf), - Val("*(&ai[0])", 1), - - Val("+1", big.NewInt(+1)), - Val("+1.0", big.NewRat(1, 1)), - Val("01.5", big.NewRat(15, 10)), - CErr("+\"x\"", opTypes), - - Val("-42", big.NewInt(-42)), - Val("-i", -1), - Val("-f", -1.0), - // 6g bug? - //Val("-(f-1)", -0.0), - CErr("-\"x\"", opTypes), - - // TODO(austin) Test unary ! - - Val("^2", big.NewInt(^2)), - Val("^(-2)", big.NewInt(^(-2))), - CErr("^2.0", opTypes), - CErr("^2.5", opTypes), - Val("^i", ^1), - Val("^u", ^uint(1)), - CErr("^f", opTypes), - - Val("1+i", 2), - Val("1+u", uint(2)), - Val("3.0+i", 4), - Val("1+1", big.NewInt(2)), - Val("f+f", 2.0), - Val("1+f", 2.0), - Val("1.0+1", big.NewRat(2, 1)), - Val("\"abc\" + \"def\"", "abcdef"), - CErr("i+u", opTypes), - CErr("-1+u", constantUnderflows), - // TODO(austin) Test named types - - Val("2-1", big.NewInt(1)), - Val("2.0-1", big.NewRat(1, 1)), - Val("f-2", -1.0), - Val("-0.0", big.NewRat(0, 1)), - Val("2*2", big.NewInt(4)), - Val("2*i", 2), - Val("3/2", big.NewInt(1)), - Val("3/i", 3), - CErr("1/0", divByZero), - CErr("1.0/0", divByZero), - RErr("i/0", divByZero), - Val("3%2", big.NewInt(1)), - Val("i%2", 1), - CErr("3%0", divByZero), - CErr("3.0%0", opTypes), - RErr("i%0", divByZero), - - // Examples from "Arithmetic operators" - Val("5/3", big.NewInt(1)), - Val("(i+4)/(i+2)", 1), - Val("5%3", big.NewInt(2)), - Val("(i+4)%(i+2)", 2), - Val("-5/3", big.NewInt(-1)), - Val("(i-6)/(i+2)", -1), - Val("-5%3", big.NewInt(-2)), - Val("(i-6)%(i+2)", -2), - Val("5/-3", big.NewInt(-1)), - Val("(i+4)/(i-4)", -1), - Val("5%-3", big.NewInt(2)), - Val("(i+4)%(i-4)", 2), - Val("-5/-3", big.NewInt(1)), - Val("(i-6)/(i-4)", 1), - Val("-5%-3", big.NewInt(-2)), - Val("(i-6)%(i-4)", -2), - - // Examples from "Arithmetic operators" - Val("11/4", big.NewInt(2)), - Val("(i+10)/4", 2), - Val("11%4", big.NewInt(3)), - Val("(i+10)%4", 3), - Val("11>>2", big.NewInt(2)), - Val("(i+10)>>2", 2), - Val("11&3", big.NewInt(3)), - Val("(i+10)&3", 3), - Val("-11/4", big.NewInt(-2)), - Val("(i-12)/4", -2), - Val("-11%4", big.NewInt(-3)), - Val("(i-12)%4", -3), - Val("-11>>2", big.NewInt(-3)), - Val("(i-12)>>2", -3), - Val("-11&3", big.NewInt(1)), - Val("(i-12)&3", 1), - - // TODO(austin) Test bit ops - - // For shift, we try nearly every combination of positive - // ideal int, negative ideal int, big ideal int, ideal - // fractional float, ideal non-fractional float, int, uint, - // and float. - Val("2<<2", big.NewInt(2<<2)), - CErr("2<<(-1)", constantUnderflows), - CErr("2<<0x10000000000000000", constantOverflows), - CErr("2<<2.5", constantTruncated), - Val("2<<2.0", big.NewInt(2<<2.0)), - CErr("2<<i", mustBeUnsigned), - Val("2<<u", 2<<1), - CErr("2<<f", opTypes), - - Val("-2<<2", big.NewInt(-2<<2)), - CErr("-2<<(-1)", constantUnderflows), - CErr("-2<<0x10000000000000000", constantOverflows), - CErr("-2<<2.5", constantTruncated), - Val("-2<<2.0", big.NewInt(-2<<2.0)), - CErr("-2<<i", mustBeUnsigned), - Val("-2<<u", -2<<1), - CErr("-2<<f", opTypes), - - Val("0x10000000000000000<<2", new(big.Int).Lsh(hugeInteger, 2)), - CErr("0x10000000000000000<<(-1)", constantUnderflows), - CErr("0x10000000000000000<<0x10000000000000000", constantOverflows), - CErr("0x10000000000000000<<2.5", constantTruncated), - Val("0x10000000000000000<<2.0", new(big.Int).Lsh(hugeInteger, 2)), - CErr("0x10000000000000000<<i", mustBeUnsigned), - CErr("0x10000000000000000<<u", constantOverflows), - CErr("0x10000000000000000<<f", opTypes), - - CErr("2.5<<2", opTypes), - CErr("2.0<<2", opTypes), - - Val("i<<2", 1<<2), - CErr("i<<(-1)", constantUnderflows), - CErr("i<<0x10000000000000000", constantOverflows), - CErr("i<<2.5", constantTruncated), - Val("i<<2.0", 1<<2), - CErr("i<<i", mustBeUnsigned), - Val("i<<u", 1<<1), - CErr("i<<f", opTypes), - Val("i<<u", 1<<1), - - Val("u<<2", uint(1<<2)), - CErr("u<<(-1)", constantUnderflows), - CErr("u<<0x10000000000000000", constantOverflows), - CErr("u<<2.5", constantTruncated), - Val("u<<2.0", uint(1<<2)), - CErr("u<<i", mustBeUnsigned), - Val("u<<u", uint(1<<1)), - CErr("u<<f", opTypes), - Val("u<<u", uint(1<<1)), - - CErr("f<<2", opTypes), - - // <, <=, >, >= - Val("1<2", 1 < 2), - Val("1<=2", 1 <= 2), - Val("2<=2", 2 <= 2), - Val("1>2", 1 > 2), - Val("1>=2", 1 >= 2), - Val("2>=2", 2 >= 2), - - Val("i<2", 1 < 2), - Val("i<=2", 1 <= 2), - Val("i+1<=2", 2 <= 2), - Val("i>2", 1 > 2), - Val("i>=2", 1 >= 2), - Val("i+1>=2", 2 >= 2), - - Val("u<2", 1 < 2), - Val("f<2", 1 < 2), - - Val("s<\"b\"", true), - Val("s<\"a\"", false), - Val("s<=\"abc\"", true), - Val("s>\"aa\"", true), - Val("s>\"ac\"", false), - Val("s>=\"abc\"", true), - - CErr("i<u", opTypes), - CErr("i<f", opTypes), - CErr("i<s", opTypes), - CErr("&i<&i", opTypes), - CErr("ai<ai", opTypes), - - // ==, != - Val("1==1", true), - Val("1!=1", false), - Val("1==2", false), - Val("1!=2", true), - - Val("1.0==1", true), - Val("1.5==1", false), - - Val("i==1", true), - Val("i!=1", false), - Val("i==2", false), - Val("i!=2", true), - - Val("u==1", true), - Val("f==1", true), - - Val("s==\"abc\"", true), - Val("s!=\"abc\"", false), - Val("s==\"abcd\"", false), - Val("s!=\"abcd\"", true), - - Val("&i==&i", true), - Val("&i==&i2", false), - - Val("fn==fn", true), - Val("fn==func(int)int{return 0}", false), - - CErr("i==u", opTypes), - CErr("i==f", opTypes), - CErr("&i==&f", opTypes), - CErr("ai==ai", opTypes), - CErr("t==t", opTypes), - CErr("fn==oneTwo", opTypes), -} - -func TestExpr(t *testing.T) { runTests(t, "exprTests", exprTests) } diff --git a/libgo/go/exp/eval/func.go b/libgo/go/exp/eval/func.go deleted file mode 100644 index cb1b579e42c..00000000000 --- a/libgo/go/exp/eval/func.go +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package eval - -import "os" - -/* - * Virtual machine - */ - -type Thread struct { - abort chan os.Error - pc uint - // The execution frame of this function. This remains the - // same throughout a function invocation. - f *Frame -} - -type code []func(*Thread) - -func (i code) exec(t *Thread) { - opc := t.pc - t.pc = 0 - l := uint(len(i)) - for t.pc < l { - pc := t.pc - t.pc++ - i[pc](t) - } - t.pc = opc -} - -/* - * Code buffer - */ - -type codeBuf struct { - instrs code -} - -func newCodeBuf() *codeBuf { return &codeBuf{make(code, 0, 16)} } - -func (b *codeBuf) push(instr func(*Thread)) { - b.instrs = append(b.instrs, instr) -} - -func (b *codeBuf) nextPC() uint { return uint(len(b.instrs)) } - -func (b *codeBuf) get() code { - // Freeze this buffer into an array of exactly the right size - a := make(code, len(b.instrs)) - copy(a, b.instrs) - return code(a) -} - -/* - * User-defined functions - */ - -type evalFunc struct { - outer *Frame - frameSize int - code code -} - -func (f *evalFunc) NewFrame() *Frame { return f.outer.child(f.frameSize) } - -func (f *evalFunc) Call(t *Thread) { f.code.exec(t) } diff --git a/libgo/go/exp/eval/scope.go b/libgo/go/exp/eval/scope.go deleted file mode 100644 index 66305de25f0..00000000000 --- a/libgo/go/exp/eval/scope.go +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package eval - -import ( - "go/token" - "log" -) - -/* - * Blocks and scopes - */ - -// A definition can be a *Variable, *Constant, or Type. -type Def interface { - Pos() token.Pos -} - -type Variable struct { - VarPos token.Pos - // Index of this variable in the Frame structure - Index int - // Static type of this variable - Type Type - // Value of this variable. This is only used by Scope.NewFrame; - // therefore, it is useful for global scopes but cannot be used - // in function scopes. - Init Value -} - -func (v *Variable) Pos() token.Pos { - return v.VarPos -} - -type Constant struct { - ConstPos token.Pos - Type Type - Value Value -} - -func (c *Constant) Pos() token.Pos { - return c.ConstPos -} - -// A block represents a definition block in which a name may not be -// defined more than once. -type block struct { - // The block enclosing this one, including blocks in other - // scopes. - outer *block - // The nested block currently being compiled, or nil. - inner *block - // The Scope containing this block. - scope *Scope - // The Variables, Constants, and Types defined in this block. - defs map[string]Def - // The index of the first variable defined in this block. - // This must be greater than the index of any variable defined - // in any parent of this block within the same Scope at the - // time this block is entered. - offset int - // The number of Variables defined in this block. - numVars int - // If global, do not allocate new vars and consts in - // the frame; assume that the refs will be compiled in - // using defs[name].Init. - global bool -} - -// A Scope is the compile-time analogue of a Frame, which captures -// some subtree of blocks. -type Scope struct { - // The root block of this scope. - *block - // The maximum number of variables required at any point in - // this Scope. This determines the number of slots needed in - // Frame's created from this Scope at run-time. - maxVars int -} - -func (b *block) enterChild() *block { - if b.inner != nil && b.inner.scope == b.scope { - log.Panic("Failed to exit child block before entering another child") - } - sub := &block{ - outer: b, - scope: b.scope, - defs: make(map[string]Def), - offset: b.offset + b.numVars, - } - b.inner = sub - return sub -} - -func (b *block) exit() { - if b.outer == nil { - log.Panic("Cannot exit top-level block") - } - if b.outer.scope == b.scope { - if b.outer.inner != b { - log.Panic("Already exited block") - } - if b.inner != nil && b.inner.scope == b.scope { - log.Panic("Exit of parent block without exit of child block") - } - } - b.outer.inner = nil -} - -func (b *block) ChildScope() *Scope { - if b.inner != nil && b.inner.scope == b.scope { - log.Panic("Failed to exit child block before entering a child scope") - } - sub := b.enterChild() - sub.offset = 0 - sub.scope = &Scope{sub, 0} - return sub.scope -} - -func (b *block) DefineVar(name string, pos token.Pos, t Type) (*Variable, Def) { - if prev, ok := b.defs[name]; ok { - return nil, prev - } - v := b.defineSlot(t, false) - v.VarPos = pos - b.defs[name] = v - return v, nil -} - -func (b *block) DefineTemp(t Type) *Variable { return b.defineSlot(t, true) } - -func (b *block) defineSlot(t Type, temp bool) *Variable { - if b.inner != nil && b.inner.scope == b.scope { - log.Panic("Failed to exit child block before defining variable") - } - index := -1 - if !b.global || temp { - index = b.offset + b.numVars - b.numVars++ - if index >= b.scope.maxVars { - b.scope.maxVars = index + 1 - } - } - v := &Variable{token.NoPos, index, t, nil} - return v -} - -func (b *block) DefineConst(name string, pos token.Pos, t Type, v Value) (*Constant, Def) { - if prev, ok := b.defs[name]; ok { - return nil, prev - } - c := &Constant{pos, t, v} - b.defs[name] = c - return c, nil -} - -func (b *block) DefineType(name string, pos token.Pos, t Type) Type { - if _, ok := b.defs[name]; ok { - return nil - } - nt := &NamedType{pos, name, nil, true, make(map[string]Method)} - if t != nil { - nt.Complete(t) - } - b.defs[name] = nt - return nt -} - -func (b *block) Lookup(name string) (bl *block, level int, def Def) { - for b != nil { - if d, ok := b.defs[name]; ok { - return b, level, d - } - if b.outer != nil && b.scope != b.outer.scope { - level++ - } - b = b.outer - } - return nil, 0, nil -} - -func (s *Scope) NewFrame(outer *Frame) *Frame { return outer.child(s.maxVars) } - -/* - * Frames - */ - -type Frame struct { - Outer *Frame - Vars []Value -} - -func (f *Frame) Get(level int, index int) Value { - for ; level > 0; level-- { - f = f.Outer - } - return f.Vars[index] -} - -func (f *Frame) child(numVars int) *Frame { - // TODO(austin) This is probably rather expensive. All values - // require heap allocation and zeroing them when we execute a - // definition typically requires some computation. - return &Frame{f, make([]Value, numVars)} -} diff --git a/libgo/go/exp/eval/stmt.go b/libgo/go/exp/eval/stmt.go deleted file mode 100644 index f6b7c1cda94..00000000000 --- a/libgo/go/exp/eval/stmt.go +++ /dev/null @@ -1,1299 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package eval - -import ( - "big" - "log" - "go/ast" - "go/token" -) - -const ( - returnPC = ^uint(0) - badPC = ^uint(1) -) - -/* - * Statement compiler - */ - -type stmtCompiler struct { - *blockCompiler - pos token.Pos - // This statement's label, or nil if it is not labeled. - stmtLabel *label -} - -func (a *stmtCompiler) diag(format string, args ...interface{}) { - a.diagAt(a.pos, format, args...) -} - -/* - * Flow checker - */ - -type flowEnt struct { - // Whether this flow entry is conditional. If true, flow can - // continue to the next PC. - cond bool - // True if this will terminate flow (e.g., a return statement). - // cond must be false and jumps must be nil if this is true. - term bool - // PC's that can be reached from this flow entry. - jumps []*uint - // Whether this flow entry has been visited by reachesEnd. - visited bool -} - -type flowBlock struct { - // If this is a goto, the target label. - target string - // The inner-most block containing definitions. - block *block - // The numVars from each block leading to the root of the - // scope, starting at block. - numVars []int -} - -type flowBuf struct { - cb *codeBuf - // ents is a map from PC's to flow entries. Any PC missing - // from this map is assumed to reach only PC+1. - ents map[uint]*flowEnt - // gotos is a map from goto positions to information on the - // block at the point of the goto. - gotos map[token.Pos]*flowBlock - // labels is a map from label name to information on the block - // at the point of the label. labels are tracked by name, - // since mutliple labels at the same PC can have different - // blocks. - labels map[string]*flowBlock -} - -func newFlowBuf(cb *codeBuf) *flowBuf { - return &flowBuf{cb, make(map[uint]*flowEnt), make(map[token.Pos]*flowBlock), make(map[string]*flowBlock)} -} - -// put creates a flow control point for the next PC in the code buffer. -// This should be done before pushing the instruction into the code buffer. -func (f *flowBuf) put(cond bool, term bool, jumps []*uint) { - pc := f.cb.nextPC() - if ent, ok := f.ents[pc]; ok { - log.Panicf("Flow entry already exists at PC %d: %+v", pc, ent) - } - f.ents[pc] = &flowEnt{cond, term, jumps, false} -} - -// putTerm creates a flow control point at the next PC that -// unconditionally terminates execution. -func (f *flowBuf) putTerm() { f.put(false, true, nil) } - -// put1 creates a flow control point at the next PC that jumps to one -// PC and, if cond is true, can also continue to the PC following the -// next PC. -func (f *flowBuf) put1(cond bool, jumpPC *uint) { - f.put(cond, false, []*uint{jumpPC}) -} - -func newFlowBlock(target string, b *block) *flowBlock { - // Find the inner-most block containing definitions - for b.numVars == 0 && b.outer != nil && b.outer.scope == b.scope { - b = b.outer - } - - // Count parents leading to the root of the scope - n := 0 - for bp := b; bp.scope == b.scope; bp = bp.outer { - n++ - } - - // Capture numVars from each block to the root of the scope - numVars := make([]int, n) - i := 0 - for bp := b; i < n; bp = bp.outer { - numVars[i] = bp.numVars - i++ - } - - return &flowBlock{target, b, numVars} -} - -// putGoto captures the block at a goto statement. This should be -// called in addition to putting a flow control point. -func (f *flowBuf) putGoto(pos token.Pos, target string, b *block) { - f.gotos[pos] = newFlowBlock(target, b) -} - -// putLabel captures the block at a label. -func (f *flowBuf) putLabel(name string, b *block) { - f.labels[name] = newFlowBlock("", b) -} - -// reachesEnd returns true if the end of f's code buffer can be -// reached from the given program counter. Error reporting is the -// caller's responsibility. -func (f *flowBuf) reachesEnd(pc uint) bool { - endPC := f.cb.nextPC() - if pc > endPC { - log.Panicf("Reached bad PC %d past end PC %d", pc, endPC) - } - - for ; pc < endPC; pc++ { - ent, ok := f.ents[pc] - if !ok { - continue - } - - if ent.visited { - return false - } - ent.visited = true - - if ent.term { - return false - } - - // If anything can reach the end, we can reach the end - // from pc. - for _, j := range ent.jumps { - if f.reachesEnd(*j) { - return true - } - } - // If the jump was conditional, we can reach the next - // PC, so try reaching the end from it. - if ent.cond { - continue - } - return false - } - return true -} - -// gotosObeyScopes returns true if no goto statement causes any -// variables to come into scope that were not in scope at the point of -// the goto. Reports any errors using the given compiler. -func (f *flowBuf) gotosObeyScopes(a *compiler) { - for pos, src := range f.gotos { - tgt := f.labels[src.target] - - // The target block must be a parent of this block - numVars := src.numVars - b := src.block - for len(numVars) > 0 && b != tgt.block { - b = b.outer - numVars = numVars[1:] - } - if b != tgt.block { - // We jumped into a deeper block - a.diagAt(pos, "goto causes variables to come into scope") - return - } - - // There must be no variables in the target block that - // did not exist at the jump - tgtNumVars := tgt.numVars - for i := range numVars { - if tgtNumVars[i] > numVars[i] { - a.diagAt(pos, "goto causes variables to come into scope") - return - } - } - } -} - -/* - * Statement generation helpers - */ - -func (a *stmtCompiler) defineVar(ident *ast.Ident, t Type) *Variable { - v, prev := a.block.DefineVar(ident.Name, ident.Pos(), t) - if prev != nil { - if prev.Pos().IsValid() { - a.diagAt(ident.Pos(), "variable %s redeclared in this block\n\tprevious declaration at %s", ident.Name, a.fset.Position(prev.Pos())) - } else { - a.diagAt(ident.Pos(), "variable %s redeclared in this block", ident.Name) - } - return nil - } - - // Initialize the variable - index := v.Index - if v.Index >= 0 { - a.push(func(v *Thread) { v.f.Vars[index] = t.Zero() }) - } - return v -} - -// TODO(austin) Move doAssign to here - -/* - * Statement compiler - */ - -func (a *stmtCompiler) compile(s ast.Stmt) { - if a.block.inner != nil { - log.Panic("Child scope still entered") - } - - notimpl := false - switch s := s.(type) { - case *ast.BadStmt: - // Error already reported by parser. - a.silentErrors++ - - case *ast.DeclStmt: - a.compileDeclStmt(s) - - case *ast.EmptyStmt: - // Do nothing. - - case *ast.LabeledStmt: - a.compileLabeledStmt(s) - - case *ast.ExprStmt: - a.compileExprStmt(s) - - case *ast.IncDecStmt: - a.compileIncDecStmt(s) - - case *ast.AssignStmt: - a.compileAssignStmt(s) - - case *ast.GoStmt: - notimpl = true - - case *ast.DeferStmt: - notimpl = true - - case *ast.ReturnStmt: - a.compileReturnStmt(s) - - case *ast.BranchStmt: - a.compileBranchStmt(s) - - case *ast.BlockStmt: - a.compileBlockStmt(s) - - case *ast.IfStmt: - a.compileIfStmt(s) - - case *ast.CaseClause: - a.diag("case clause outside switch") - - case *ast.SwitchStmt: - a.compileSwitchStmt(s) - - case *ast.TypeSwitchStmt: - notimpl = true - - case *ast.CommClause: - notimpl = true - - case *ast.SelectStmt: - notimpl = true - - case *ast.ForStmt: - a.compileForStmt(s) - - case *ast.RangeStmt: - notimpl = true - - default: - log.Panicf("unexpected ast node type %T", s) - } - - if notimpl { - a.diag("%T statment node not implemented", s) - } - - if a.block.inner != nil { - log.Panic("Forgot to exit child scope") - } -} - -func (a *stmtCompiler) compileDeclStmt(s *ast.DeclStmt) { - switch decl := s.Decl.(type) { - case *ast.BadDecl: - // Do nothing. Already reported by parser. - a.silentErrors++ - - case *ast.FuncDecl: - if !a.block.global { - log.Panic("FuncDecl at statement level") - } - - case *ast.GenDecl: - if decl.Tok == token.IMPORT && !a.block.global { - log.Panic("import at statement level") - } - - default: - log.Panicf("Unexpected Decl type %T", s.Decl) - } - a.compileDecl(s.Decl) -} - -func (a *stmtCompiler) compileVarDecl(decl *ast.GenDecl) { - for _, spec := range decl.Specs { - spec := spec.(*ast.ValueSpec) - if spec.Values == nil { - // Declaration without assignment - if spec.Type == nil { - // Parser should have caught - log.Panic("Type and Values nil") - } - t := a.compileType(a.block, spec.Type) - // Define placeholders even if type compile failed - for _, n := range spec.Names { - a.defineVar(n, t) - } - } else { - // Declaration with assignment - lhs := make([]ast.Expr, len(spec.Names)) - for i, n := range spec.Names { - lhs[i] = n - } - a.doAssign(lhs, spec.Values, decl.Tok, spec.Type) - } - } -} - -func (a *stmtCompiler) compileDecl(decl ast.Decl) { - switch d := decl.(type) { - case *ast.BadDecl: - // Do nothing. Already reported by parser. - a.silentErrors++ - - case *ast.FuncDecl: - decl := a.compileFuncType(a.block, d.Type) - if decl == nil { - return - } - // Declare and initialize v before compiling func - // so that body can refer to itself. - c, prev := a.block.DefineConst(d.Name.Name, a.pos, decl.Type, decl.Type.Zero()) - if prev != nil { - pos := prev.Pos() - if pos.IsValid() { - a.diagAt(d.Name.Pos(), "identifier %s redeclared in this block\n\tprevious declaration at %s", d.Name.Name, a.fset.Position(pos)) - } else { - a.diagAt(d.Name.Pos(), "identifier %s redeclared in this block", d.Name.Name) - } - } - fn := a.compileFunc(a.block, decl, d.Body) - if c == nil || fn == nil { - return - } - var zeroThread Thread - c.Value.(FuncValue).Set(nil, fn(&zeroThread)) - - case *ast.GenDecl: - switch d.Tok { - case token.IMPORT: - log.Panicf("%v not implemented", d.Tok) - case token.CONST: - log.Panicf("%v not implemented", d.Tok) - case token.TYPE: - a.compileTypeDecl(a.block, d) - case token.VAR: - a.compileVarDecl(d) - } - - default: - log.Panicf("Unexpected Decl type %T", decl) - } -} - -func (a *stmtCompiler) compileLabeledStmt(s *ast.LabeledStmt) { - // Define label - l, ok := a.labels[s.Label.Name] - if ok { - if l.resolved.IsValid() { - a.diag("label %s redeclared in this block\n\tprevious declaration at %s", s.Label.Name, a.fset.Position(l.resolved)) - } - } else { - pc := badPC - l = &label{name: s.Label.Name, gotoPC: &pc} - a.labels[l.name] = l - } - l.desc = "regular label" - l.resolved = s.Pos() - - // Set goto PC - *l.gotoPC = a.nextPC() - - // Define flow entry so we can check for jumps over declarations. - a.flow.putLabel(l.name, a.block) - - // Compile the statement. Reuse our stmtCompiler for simplicity. - sc := &stmtCompiler{a.blockCompiler, s.Stmt.Pos(), l} - sc.compile(s.Stmt) -} - -func (a *stmtCompiler) compileExprStmt(s *ast.ExprStmt) { - bc := a.enterChild() - defer bc.exit() - - e := a.compileExpr(bc.block, false, s.X) - if e == nil { - return - } - - if e.exec == nil { - a.diag("%s cannot be used as expression statement", e.desc) - return - } - - a.push(e.exec) -} - -func (a *stmtCompiler) compileIncDecStmt(s *ast.IncDecStmt) { - // Create temporary block for extractEffect - bc := a.enterChild() - defer bc.exit() - - l := a.compileExpr(bc.block, false, s.X) - if l == nil { - return - } - - if l.evalAddr == nil { - l.diag("cannot assign to %s", l.desc) - return - } - if !(l.t.isInteger() || l.t.isFloat()) { - l.diagOpType(s.Tok, l.t) - return - } - - var op token.Token - var desc string - switch s.Tok { - case token.INC: - op = token.ADD - desc = "increment statement" - case token.DEC: - op = token.SUB - desc = "decrement statement" - default: - log.Panicf("Unexpected IncDec token %v", s.Tok) - } - - effect, l := l.extractEffect(bc.block, desc) - - one := l.newExpr(IdealIntType, "constant") - one.pos = s.Pos() - one.eval = func() *big.Int { return big.NewInt(1) } - - binop := l.compileBinaryExpr(op, l, one) - if binop == nil { - return - } - - assign := a.compileAssign(s.Pos(), bc.block, l.t, []*expr{binop}, "", "") - if assign == nil { - log.Panicf("compileAssign type check failed") - } - - lf := l.evalAddr - a.push(func(v *Thread) { - effect(v) - assign(lf(v), v) - }) -} - -func (a *stmtCompiler) doAssign(lhs []ast.Expr, rhs []ast.Expr, tok token.Token, declTypeExpr ast.Expr) { - nerr := a.numError() - - // Compile right side first so we have the types when - // compiling the left side and so we don't see definitions - // made on the left side. - rs := make([]*expr, len(rhs)) - for i, re := range rhs { - rs[i] = a.compileExpr(a.block, false, re) - } - - errOp := "assignment" - if tok == token.DEFINE || tok == token.VAR { - errOp = "declaration" - } - ac, ok := a.checkAssign(a.pos, rs, errOp, "value") - ac.allowMapForms(len(lhs)) - - // If this is a definition and the LHS is too big, we won't be - // able to produce the usual error message because we can't - // begin to infer the types of the LHS. - if (tok == token.DEFINE || tok == token.VAR) && len(lhs) > len(ac.rmt.Elems) { - a.diag("not enough values for definition") - } - - // Compile left type if there is one - var declType Type - if declTypeExpr != nil { - declType = a.compileType(a.block, declTypeExpr) - } - - // Compile left side - ls := make([]*expr, len(lhs)) - nDefs := 0 - for i, le := range lhs { - // If this is a definition, get the identifier and its type - var ident *ast.Ident - var lt Type - switch tok { - case token.DEFINE: - // Check that it's an identifier - ident, ok = le.(*ast.Ident) - if !ok { - a.diagAt(le.Pos(), "left side of := must be a name") - // Suppress new defitions errors - nDefs++ - continue - } - - // Is this simply an assignment? - if _, ok := a.block.defs[ident.Name]; ok { - ident = nil - break - } - nDefs++ - - case token.VAR: - ident = le.(*ast.Ident) - } - - // If it's a definition, get or infer its type. - if ident != nil { - // Compute the identifier's type from the RHS - // type. We use the computed MultiType so we - // don't have to worry about unpacking. - switch { - case declTypeExpr != nil: - // We have a declaration type, use it. - // If declType is nil, we gave an - // error when we compiled it. - lt = declType - - case i >= len(ac.rmt.Elems): - // Define a placeholder. We already - // gave the "not enough" error above. - lt = nil - - case ac.rmt.Elems[i] == nil: - // We gave the error when we compiled - // the RHS. - lt = nil - - case ac.rmt.Elems[i].isIdeal(): - // If the type is absent and the - // corresponding expression is a - // constant expression of ideal - // integer or ideal float type, the - // type of the declared variable is - // int or float respectively. - switch { - case ac.rmt.Elems[i].isInteger(): - lt = IntType - case ac.rmt.Elems[i].isFloat(): - lt = Float64Type - default: - log.Panicf("unexpected ideal type %v", rs[i].t) - } - - default: - lt = ac.rmt.Elems[i] - } - } - - // If it's a definition, define the identifier - if ident != nil { - if a.defineVar(ident, lt) == nil { - continue - } - } - - // Compile LHS - ls[i] = a.compileExpr(a.block, false, le) - if ls[i] == nil { - continue - } - - if ls[i].evalMapValue != nil { - // Map indexes are not generally addressable, - // but they are assignable. - // - // TODO(austin) Now that the expression - // compiler uses semantic values, this might - // be easier to implement as a function call. - sub := ls[i] - ls[i] = ls[i].newExpr(sub.t, sub.desc) - ls[i].evalMapValue = sub.evalMapValue - mvf := sub.evalMapValue - et := sub.t - ls[i].evalAddr = func(t *Thread) Value { - m, k := mvf(t) - e := m.Elem(t, k) - if e == nil { - e = et.Zero() - m.SetElem(t, k, e) - } - return e - } - } else if ls[i].evalAddr == nil { - ls[i].diag("cannot assign to %s", ls[i].desc) - continue - } - } - - // A short variable declaration may redeclare variables - // provided they were originally declared in the same block - // with the same type, and at least one of the variables is - // new. - if tok == token.DEFINE && nDefs == 0 { - a.diag("at least one new variable must be declared") - return - } - - // If there have been errors, our arrays are full of nil's so - // get out of here now. - if nerr != a.numError() { - return - } - - // Check for 'a[x] = r, ok' - if len(ls) == 1 && len(rs) == 2 && ls[0].evalMapValue != nil { - a.diag("a[x] = r, ok form not implemented") - return - } - - // Create assigner - var lt Type - n := len(lhs) - if n == 1 { - lt = ls[0].t - } else { - lts := make([]Type, len(ls)) - for i, l := range ls { - if l != nil { - lts[i] = l.t - } - } - lt = NewMultiType(lts) - } - bc := a.enterChild() - defer bc.exit() - assign := ac.compile(bc.block, lt) - if assign == nil { - return - } - - // Compile - if n == 1 { - // Don't need temporaries and can avoid []Value. - lf := ls[0].evalAddr - a.push(func(t *Thread) { assign(lf(t), t) }) - } else if tok == token.VAR || (tok == token.DEFINE && nDefs == n) { - // Don't need temporaries - lfs := make([]func(*Thread) Value, n) - for i, l := range ls { - lfs[i] = l.evalAddr - } - a.push(func(t *Thread) { - dest := make([]Value, n) - for i, lf := range lfs { - dest[i] = lf(t) - } - assign(multiV(dest), t) - }) - } else { - // Need temporaries - lmt := lt.(*MultiType) - lfs := make([]func(*Thread) Value, n) - for i, l := range ls { - lfs[i] = l.evalAddr - } - a.push(func(t *Thread) { - temp := lmt.Zero().(multiV) - assign(temp, t) - // Copy to destination - for i := 0; i < n; i++ { - // TODO(austin) Need to evaluate LHS - // before RHS - lfs[i](t).Assign(t, temp[i]) - } - }) - } -} - -var assignOpToOp = map[token.Token]token.Token{ - token.ADD_ASSIGN: token.ADD, - token.SUB_ASSIGN: token.SUB, - token.MUL_ASSIGN: token.MUL, - token.QUO_ASSIGN: token.QUO, - token.REM_ASSIGN: token.REM, - - token.AND_ASSIGN: token.AND, - token.OR_ASSIGN: token.OR, - token.XOR_ASSIGN: token.XOR, - token.SHL_ASSIGN: token.SHL, - token.SHR_ASSIGN: token.SHR, - token.AND_NOT_ASSIGN: token.AND_NOT, -} - -func (a *stmtCompiler) doAssignOp(s *ast.AssignStmt) { - if len(s.Lhs) != 1 || len(s.Rhs) != 1 { - a.diag("tuple assignment cannot be combined with an arithmetic operation") - return - } - - // Create temporary block for extractEffect - bc := a.enterChild() - defer bc.exit() - - l := a.compileExpr(bc.block, false, s.Lhs[0]) - r := a.compileExpr(bc.block, false, s.Rhs[0]) - if l == nil || r == nil { - return - } - - if l.evalAddr == nil { - l.diag("cannot assign to %s", l.desc) - return - } - - effect, l := l.extractEffect(bc.block, "operator-assignment") - - binop := r.compileBinaryExpr(assignOpToOp[s.Tok], l, r) - if binop == nil { - return - } - - assign := a.compileAssign(s.Pos(), bc.block, l.t, []*expr{binop}, "assignment", "value") - if assign == nil { - log.Panicf("compileAssign type check failed") - } - - lf := l.evalAddr - a.push(func(t *Thread) { - effect(t) - assign(lf(t), t) - }) -} - -func (a *stmtCompiler) compileAssignStmt(s *ast.AssignStmt) { - switch s.Tok { - case token.ASSIGN, token.DEFINE: - a.doAssign(s.Lhs, s.Rhs, s.Tok, nil) - - default: - a.doAssignOp(s) - } -} - -func (a *stmtCompiler) compileReturnStmt(s *ast.ReturnStmt) { - if a.fnType == nil { - a.diag("cannot return at the top level") - return - } - - if len(s.Results) == 0 && (len(a.fnType.Out) == 0 || a.outVarsNamed) { - // Simple case. Simply exit from the function. - a.flow.putTerm() - a.push(func(v *Thread) { v.pc = returnPC }) - return - } - - bc := a.enterChild() - defer bc.exit() - - // Compile expressions - bad := false - rs := make([]*expr, len(s.Results)) - for i, re := range s.Results { - rs[i] = a.compileExpr(bc.block, false, re) - if rs[i] == nil { - bad = true - } - } - if bad { - return - } - - // Create assigner - - // However, if the expression list in the "return" statement - // is a single call to a multi-valued function, the values - // returned from the called function will be returned from - // this one. - assign := a.compileAssign(s.Pos(), bc.block, NewMultiType(a.fnType.Out), rs, "return", "value") - - // XXX(Spec) "The result types of the current function and the - // called function must match." Match is fuzzy. It should - // say that they must be assignment compatible. - - // Compile - start := len(a.fnType.In) - nout := len(a.fnType.Out) - a.flow.putTerm() - a.push(func(t *Thread) { - assign(multiV(t.f.Vars[start:start+nout]), t) - t.pc = returnPC - }) -} - -func (a *stmtCompiler) findLexicalLabel(name *ast.Ident, pred func(*label) bool, errOp, errCtx string) *label { - bc := a.blockCompiler - for ; bc != nil; bc = bc.parent { - if bc.label == nil { - continue - } - l := bc.label - if name == nil && pred(l) { - return l - } - if name != nil && l.name == name.Name { - if !pred(l) { - a.diag("cannot %s to %s %s", errOp, l.desc, l.name) - return nil - } - return l - } - } - if name == nil { - a.diag("%s outside %s", errOp, errCtx) - } else { - a.diag("%s label %s not defined", errOp, name.Name) - } - return nil -} - -func (a *stmtCompiler) compileBranchStmt(s *ast.BranchStmt) { - var pc *uint - - switch s.Tok { - case token.BREAK: - l := a.findLexicalLabel(s.Label, func(l *label) bool { return l.breakPC != nil }, "break", "for loop, switch, or select") - if l == nil { - return - } - pc = l.breakPC - - case token.CONTINUE: - l := a.findLexicalLabel(s.Label, func(l *label) bool { return l.continuePC != nil }, "continue", "for loop") - if l == nil { - return - } - pc = l.continuePC - - case token.GOTO: - l, ok := a.labels[s.Label.Name] - if !ok { - pc := badPC - l = &label{name: s.Label.Name, desc: "unresolved label", gotoPC: &pc, used: s.Pos()} - a.labels[l.name] = l - } - - pc = l.gotoPC - a.flow.putGoto(s.Pos(), l.name, a.block) - - case token.FALLTHROUGH: - a.diag("fallthrough outside switch") - return - - default: - log.Panicf("Unexpected branch token %v", s.Tok) - } - - a.flow.put1(false, pc) - a.push(func(v *Thread) { v.pc = *pc }) -} - -func (a *stmtCompiler) compileBlockStmt(s *ast.BlockStmt) { - bc := a.enterChild() - bc.compileStmts(s) - bc.exit() -} - -func (a *stmtCompiler) compileIfStmt(s *ast.IfStmt) { - // The scope of any variables declared by [the init] statement - // extends to the end of the "if" statement and the variables - // are initialized once before the statement is entered. - // - // XXX(Spec) What this really wants to say is that there's an - // implicit scope wrapping every if, for, and switch - // statement. This is subtly different from what it actually - // says when there's a non-block else clause, because that - // else claus has to execute in a scope that is *not* the - // surrounding scope. - bc := a.enterChild() - defer bc.exit() - - // Compile init statement, if any - if s.Init != nil { - bc.compileStmt(s.Init) - } - - elsePC := badPC - endPC := badPC - - // Compile condition, if any. If there is no condition, we - // fall through to the body. - if s.Cond != nil { - e := bc.compileExpr(bc.block, false, s.Cond) - switch { - case e == nil: - // Error reported by compileExpr - case !e.t.isBoolean(): - e.diag("'if' condition must be boolean\n\t%v", e.t) - default: - eval := e.asBool() - a.flow.put1(true, &elsePC) - a.push(func(t *Thread) { - if !eval(t) { - t.pc = elsePC - } - }) - } - } - - // Compile body - body := bc.enterChild() - body.compileStmts(s.Body) - body.exit() - - // Compile else - if s.Else != nil { - // Skip over else if we executed the body - a.flow.put1(false, &endPC) - a.push(func(v *Thread) { v.pc = endPC }) - elsePC = a.nextPC() - bc.compileStmt(s.Else) - } else { - elsePC = a.nextPC() - } - endPC = a.nextPC() -} - -func (a *stmtCompiler) compileSwitchStmt(s *ast.SwitchStmt) { - // Create implicit scope around switch - bc := a.enterChild() - defer bc.exit() - - // Compile init statement, if any - if s.Init != nil { - bc.compileStmt(s.Init) - } - - // Compile condition, if any, and extract its effects - var cond *expr - condbc := bc.enterChild() - if s.Tag != nil { - e := condbc.compileExpr(condbc.block, false, s.Tag) - if e != nil { - var effect func(*Thread) - effect, cond = e.extractEffect(condbc.block, "switch") - a.push(effect) - } - } - - // Count cases - ncases := 0 - hasDefault := false - for _, c := range s.Body.List { - clause, ok := c.(*ast.CaseClause) - if !ok { - a.diagAt(clause.Pos(), "switch statement must contain case clauses") - continue - } - if clause.List == nil { - if hasDefault { - a.diagAt(clause.Pos(), "switch statement contains more than one default case") - } - hasDefault = true - } else { - ncases += len(clause.List) - } - } - - // Compile case expressions - cases := make([]func(*Thread) bool, ncases) - i := 0 - for _, c := range s.Body.List { - clause, ok := c.(*ast.CaseClause) - if !ok { - continue - } - for _, v := range clause.List { - e := condbc.compileExpr(condbc.block, false, v) - switch { - case e == nil: - // Error reported by compileExpr - case cond == nil && !e.t.isBoolean(): - a.diagAt(v.Pos(), "'case' condition must be boolean") - case cond == nil: - cases[i] = e.asBool() - case cond != nil: - // Create comparison - // TOOD(austin) This produces bad error messages - compare := e.compileBinaryExpr(token.EQL, cond, e) - if compare != nil { - cases[i] = compare.asBool() - } - } - i++ - } - } - - // Emit condition - casePCs := make([]*uint, ncases+1) - endPC := badPC - - a.flow.put(false, false, casePCs) - a.push(func(t *Thread) { - for i, c := range cases { - if c(t) { - t.pc = *casePCs[i] - return - } - } - t.pc = *casePCs[ncases] - }) - condbc.exit() - - // Compile cases - i = 0 - for _, c := range s.Body.List { - clause, ok := c.(*ast.CaseClause) - if !ok { - continue - } - - // Save jump PC's - pc := a.nextPC() - if clause.List != nil { - for _ = range clause.List { - casePCs[i] = &pc - i++ - } - } else { - // Default clause - casePCs[ncases] = &pc - } - - // Compile body - fall := false - for j, s := range clause.Body { - if br, ok := s.(*ast.BranchStmt); ok && br.Tok == token.FALLTHROUGH { - // println("Found fallthrough"); - // It may be used only as the final - // non-empty statement in a case or - // default clause in an expression - // "switch" statement. - for _, s2 := range clause.Body[j+1:] { - // XXX(Spec) 6g also considers - // empty blocks to be empty - // statements. - if _, ok := s2.(*ast.EmptyStmt); !ok { - a.diagAt(s.Pos(), "fallthrough statement must be final statement in case") - break - } - } - fall = true - } else { - bc.compileStmt(s) - } - } - // Jump out of switch, unless there was a fallthrough - if !fall { - a.flow.put1(false, &endPC) - a.push(func(v *Thread) { v.pc = endPC }) - } - } - - // Get end PC - endPC = a.nextPC() - if !hasDefault { - casePCs[ncases] = &endPC - } -} - -func (a *stmtCompiler) compileForStmt(s *ast.ForStmt) { - // Wrap the entire for in a block. - bc := a.enterChild() - defer bc.exit() - - // Compile init statement, if any - if s.Init != nil { - bc.compileStmt(s.Init) - } - - bodyPC := badPC - postPC := badPC - checkPC := badPC - endPC := badPC - - // Jump to condition check. We generate slightly less code by - // placing the condition check after the body. - a.flow.put1(false, &checkPC) - a.push(func(v *Thread) { v.pc = checkPC }) - - // Compile body - bodyPC = a.nextPC() - body := bc.enterChild() - if a.stmtLabel != nil { - body.label = a.stmtLabel - } else { - body.label = &label{resolved: s.Pos()} - } - body.label.desc = "for loop" - body.label.breakPC = &endPC - body.label.continuePC = &postPC - body.compileStmts(s.Body) - body.exit() - - // Compile post, if any - postPC = a.nextPC() - if s.Post != nil { - // TODO(austin) Does the parser disallow short - // declarations in s.Post? - bc.compileStmt(s.Post) - } - - // Compile condition check, if any - checkPC = a.nextPC() - if s.Cond == nil { - // If the condition is absent, it is equivalent to true. - a.flow.put1(false, &bodyPC) - a.push(func(v *Thread) { v.pc = bodyPC }) - } else { - e := bc.compileExpr(bc.block, false, s.Cond) - switch { - case e == nil: - // Error reported by compileExpr - case !e.t.isBoolean(): - a.diag("'for' condition must be boolean\n\t%v", e.t) - default: - eval := e.asBool() - a.flow.put1(true, &bodyPC) - a.push(func(t *Thread) { - if eval(t) { - t.pc = bodyPC - } - }) - } - } - - endPC = a.nextPC() -} - -/* - * Block compiler - */ - -func (a *blockCompiler) compileStmt(s ast.Stmt) { - sc := &stmtCompiler{a, s.Pos(), nil} - sc.compile(s) -} - -func (a *blockCompiler) compileStmts(block *ast.BlockStmt) { - for _, sub := range block.List { - a.compileStmt(sub) - } -} - -func (a *blockCompiler) enterChild() *blockCompiler { - block := a.block.enterChild() - return &blockCompiler{ - funcCompiler: a.funcCompiler, - block: block, - parent: a, - } -} - -func (a *blockCompiler) exit() { a.block.exit() } - -/* - * Function compiler - */ - -func (a *compiler) compileFunc(b *block, decl *FuncDecl, body *ast.BlockStmt) func(*Thread) Func { - // Create body scope - // - // The scope of a parameter or result is the body of the - // corresponding function. - bodyScope := b.ChildScope() - defer bodyScope.exit() - for i, t := range decl.Type.In { - if decl.InNames[i] != nil { - bodyScope.DefineVar(decl.InNames[i].Name, decl.InNames[i].Pos(), t) - } else { - bodyScope.DefineTemp(t) - } - } - for i, t := range decl.Type.Out { - if decl.OutNames[i] != nil { - bodyScope.DefineVar(decl.OutNames[i].Name, decl.OutNames[i].Pos(), t) - } else { - bodyScope.DefineTemp(t) - } - } - - // Create block context - cb := newCodeBuf() - fc := &funcCompiler{ - compiler: a, - fnType: decl.Type, - outVarsNamed: len(decl.OutNames) > 0 && decl.OutNames[0] != nil, - codeBuf: cb, - flow: newFlowBuf(cb), - labels: make(map[string]*label), - } - bc := &blockCompiler{ - funcCompiler: fc, - block: bodyScope.block, - } - - // Compile body - nerr := a.numError() - bc.compileStmts(body) - fc.checkLabels() - if nerr != a.numError() { - return nil - } - - // Check that the body returned if necessary. We only check - // this if there were no errors compiling the body. - if len(decl.Type.Out) > 0 && fc.flow.reachesEnd(0) { - // XXX(Spec) Not specified. - a.diagAt(body.Rbrace, "function ends without a return statement") - return nil - } - - code := fc.get() - maxVars := bodyScope.maxVars - return func(t *Thread) Func { return &evalFunc{t.f, maxVars, code} } -} - -// Checks that labels were resolved and that all jumps obey scoping -// rules. Reports an error and set fc.err if any check fails. -func (a *funcCompiler) checkLabels() { - nerr := a.numError() - for _, l := range a.labels { - if !l.resolved.IsValid() { - a.diagAt(l.used, "label %s not defined", l.name) - } - } - if nerr != a.numError() { - // Don't check scopes if we have unresolved labels - return - } - - // Executing the "goto" statement must not cause any variables - // to come into scope that were not already in scope at the - // point of the goto. - a.flow.gotosObeyScopes(a.compiler) -} diff --git a/libgo/go/exp/eval/stmt_test.go b/libgo/go/exp/eval/stmt_test.go deleted file mode 100644 index a8a3e162041..00000000000 --- a/libgo/go/exp/eval/stmt_test.go +++ /dev/null @@ -1,343 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package eval - -import "testing" - -var atLeastOneDecl = "at least one new variable must be declared" - -var stmtTests = []test{ - // Short declarations - Val1("x := i", "x", 1), - Val1("x := f", "x", 1.0), - // Type defaulting - Val1("a := 42", "a", 42), - Val1("a := 1.0", "a", 1.0), - // Parallel assignment - Val2("a, b := 1, 2", "a", 1, "b", 2), - Val2("a, i := 1, 2", "a", 1, "i", 2), - CErr("a, i := 1, f", opTypes), - CErr("a, b := 1, 2, 3", "too many"), - CErr("a := 1, 2", "too many"), - CErr("a, b := 1", "not enough"), - // Mixed declarations - CErr("i := 1", atLeastOneDecl), - CErr("i, u := 1, 2", atLeastOneDecl), - Val2("i, x := 2, f", "i", 2, "x", 1.0), - // Various errors - CErr("1 := 2", "expected identifier"), - CErr("c, a := 1, 1", "cannot assign"), - // Unpacking - Val2("x, y := oneTwo()", "x", 1, "y", 2), - CErr("x := oneTwo()", "too many"), - CErr("x, y, z := oneTwo()", "not enough"), - CErr("x, y := oneTwo(), 2", "multi-valued"), - CErr("x := oneTwo()+2", opTypes), - // TOOD(austin) This error message is weird - CErr("x := void()", "not enough"), - // Placeholders - CErr("x := 1+\"x\"; i=x+1", opTypes), - - // Assignment - Val1("i = 2", "i", 2), - Val1("(i) = 2", "i", 2), - CErr("1 = 2", "cannot assign"), - CErr("1-1 = 2", "- expression"), - Val1("i = 2.0", "i", 2), - CErr("i = 2.2", constantTruncated), - CErr("u = -2", constantUnderflows), - CErr("i = f", opTypes), - CErr("i, u = 0, f", opTypes), - CErr("i, u = 0, f", "value 2"), - Val2("i, i2 = i2, i", "i", 2, "i2", 1), - CErr("c = 1", "cannot assign"), - - Val1("x := &i; *x = 2", "i", 2), - - Val1("ai[0] = 42", "ai", varray{42, 2}), - Val1("aai[1] = ai; ai[0] = 42", "aai", varray{varray{1, 2}, varray{1, 2}}), - Val1("aai = aai2", "aai", varray{varray{5, 6}, varray{7, 8}}), - - // Assignment conversions - Run("var sl []int; sl = &ai"), - CErr("type ST []int; type AT *[2]int; var x AT = &ai; var y ST = x", opTypes), - Run("type ST []int; var y ST = &ai"), - Run("type AT *[2]int; var x AT = &ai; var y []int = x"), - - // Op-assignment - Val1("i += 2", "i", 3), - Val("i", 1), - Val1("f += 2", "f", 3.0), - CErr("2 += 2", "cannot assign"), - CErr("i, j += 2", "cannot be combined"), - CErr("i += 2, 3", "cannot be combined"), - Val2("s2 := s; s += \"def\"", "s2", "abc", "s", "abcdef"), - CErr("s += 1", opTypes), - // Single evaluation - Val2("ai[func()int{i+=1;return 0}()] *= 3; i2 = ai[0]", "i", 2, "i2", 3), - - // Type declarations - // Identifiers - Run("type T int"), - CErr("type T x", "undefined"), - CErr("type T c", "constant"), - CErr("type T i", "variable"), - CErr("type T T", "recursive"), - CErr("type T x; type U T; var v U; v = 1", "undefined"), - // Pointer types - Run("type T *int"), - Run("type T *T"), - // Array types - Run("type T [5]int"), - Run("type T [c+42/2]int"), - Run("type T [2.0]int"), - CErr("type T [i]int", "constant expression"), - CErr("type T [2.5]int", constantTruncated), - CErr("type T [-1]int", "negative"), - CErr("type T [2]T", "recursive"), - // Struct types - Run("type T struct { a int; b int }"), - Run("type T struct { a int; int }"), - Run("type T struct { x *T }"), - Run("type T int; type U struct { T }"), - CErr("type T *int; type U struct { T }", "embedded.*pointer"), - CErr("type T *struct { T }", "embedded.*pointer"), - CErr("type T struct { a int; a int }", " a .*redeclared.*:1:17"), - CErr("type T struct { int; int }", "int .*redeclared.*:1:17"), - CErr("type T struct { int int; int }", "int .*redeclared.*:1:17"), - Run("type T struct { x *struct { T } }"), - CErr("type T struct { x struct { T } }", "recursive"), - CErr("type T struct { x }; type U struct { T }", "undefined"), - // Function types - Run("type T func()"), - Run("type T func(a, b int) int"), - Run("type T func(a, b int) (x int, y int)"), - Run("type T func(a, a int) (a int, a int)"), - Run("type T func(a, b int) (x, y int)"), - Run("type T func(int, int) (int, int)"), - CErr("type T func(x); type U T", "undefined"), - CErr("type T func(a T)", "recursive"), - // Interface types - Run("type T interface {x(a, b int) int}"), - Run("type T interface {x(a, b int) int}; type U interface {T; y(c int)}"), - CErr("type T interface {x(a int); x()}", "method x redeclared"), - CErr("type T interface {x()}; type U interface {T; x()}", "method x redeclared"), - CErr("type T int; type U interface {T}", "embedded type"), - // Parens - Run("type T (int)"), - - // Variable declarations - Val2("var x int", "i", 1, "x", 0), - Val1("var x = 1", "x", 1), - Val1("var x = 1.0", "x", 1.0), - Val1("var x int = 1.0", "x", 1), - // Placeholders - CErr("var x foo; x = 1", "undefined"), - CErr("var x foo = 1; x = 1", "undefined"), - // Redeclaration - CErr("var i, x int", " i .*redeclared"), - CErr("var x int; var x int", " x .*redeclared.*:1:5"), - - // Expression statements - CErr("x := func(){ 1-1 }", "expression statement"), - CErr("x := func(){ 1-1 }", "- expression"), - Val1("fn(2)", "i", 1), - - // IncDec statements - Val1("i++", "i", 2), - Val1("i--", "i", 0), - Val1("u++", "u", uint(2)), - Val1("u--", "u", uint(0)), - Val1("f++", "f", 2.0), - Val1("f--", "f", 0.0), - // Single evaluation - Val2("ai[func()int{i+=1;return 0}()]++; i2 = ai[0]", "i", 2, "i2", 2), - // Operand types - CErr("s++", opTypes), - CErr("s++", "'\\+\\+'"), - CErr("2++", "cannot assign"), - CErr("c++", "cannot assign"), - - // Function scoping - Val1("fn1 := func() { i=2 }; fn1()", "i", 2), - Val1("fn1 := func() { i:=2 }; fn1()", "i", 1), - Val2("fn1 := func() int { i=2; i:=3; i=4; return i }; x := fn1()", "i", 2, "x", 4), - - // Basic returns - CErr("fn1 := func() int {}", "return"), - Run("fn1 := func() {}"), - CErr("fn1 := func() (r int) {}", "return"), - Val1("fn1 := func() (r int) {return}; i = fn1()", "i", 0), - Val1("fn1 := func() (r int) {r = 2; return}; i = fn1()", "i", 2), - Val1("fn1 := func() (r int) {return 2}; i = fn1()", "i", 2), - Val1("fn1 := func(int) int {return 2}; i = fn1(1)", "i", 2), - - // Multi-valued returns - Val2("fn1 := func() (bool, int) {return true, 2}; x, y := fn1()", "x", true, "y", 2), - CErr("fn1 := func() int {return}", "not enough values"), - CErr("fn1 := func() int {return 1,2}", "too many values"), - CErr("fn1 := func() {return 1}", "too many values"), - CErr("fn1 := func() (int,int,int) {return 1,2}", "not enough values"), - Val2("fn1 := func() (int, int) {return oneTwo()}; x, y := fn1()", "x", 1, "y", 2), - CErr("fn1 := func() int {return oneTwo()}", "too many values"), - CErr("fn1 := func() (int,int,int) {return oneTwo()}", "not enough values"), - Val1("fn1 := func(x,y int) int {return x+y}; x := fn1(oneTwo())", "x", 3), - - // Return control flow - Val2("fn1 := func(x *int) bool { *x = 2; return true; *x = 3; }; x := fn1(&i)", "i", 2, "x", true), - - // Break/continue/goto/fallthrough - CErr("break", "outside"), - CErr("break foo", "break.*foo.*not defined"), - CErr("continue", "outside"), - CErr("continue foo", "continue.*foo.*not defined"), - CErr("fallthrough", "outside"), - CErr("goto foo", "foo.*not defined"), - CErr(" foo: foo:;", "foo.*redeclared.*:1:2"), - Val1("i+=2; goto L; i+=4; L: i+=8", "i", 1+2+8), - // Return checking - CErr("fn1 := func() int { goto L; return 1; L: }", "return"), - Run("fn1 := func() int { L: goto L; i = 2 }"), - Run("fn1 := func() int { return 1; L: goto L }"), - // Scope checking - Run("fn1 := func() { { L: x:=1 }; goto L }"), - CErr("fn1 := func() { { x:=1; L: }; goto L }", "into scope"), - CErr("fn1 := func() { goto L; x:=1; L: }", "into scope"), - Run("fn1 := func() { goto L; { L: x:=1 } }"), - CErr("fn1 := func() { goto L; { x:=1; L: } }", "into scope"), - - // Blocks - CErr("fn1 := func() int {{}}", "return"), - Val1("fn1 := func() bool { { return true } }; b := fn1()", "b", true), - - // If - Val2("if true { i = 2 } else { i = 3 }; i2 = 4", "i", 2, "i2", 4), - Val2("if false { i = 2 } else { i = 3 }; i2 = 4", "i", 3, "i2", 4), - Val2("if i == i2 { i = 2 } else { i = 3 }; i2 = 4", "i", 3, "i2", 4), - // Omit optional parts - Val2("if true { i = 2 } else { i = 3 }; i2 = 4", "i", 2, "i2", 4), - Val2("if true { i = 2 }; i2 = 4", "i", 2, "i2", 4), - Val2("if false { i = 2 }; i2 = 4", "i", 1, "i2", 4), - // Init - Val2("if x := true; x { i = 2 } else { i = 3 }; i2 = 4", "i", 2, "i2", 4), - Val2("if x := false; x { i = 2 } else { i = 3 }; i2 = 4", "i", 3, "i2", 4), - // Statement else - Val2("if true { i = 2 } else i = 3; i2 = 4", "i", 2, "i2", 4), - Val2("if false { i = 2 } else i = 3; i2 = 4", "i", 3, "i2", 4), - // Scoping - Val2("if true { i := 2 } else { i := 3 }; i2 = i", "i", 1, "i2", 1), - Val2("if false { i := 2 } else { i := 3 }; i2 = i", "i", 1, "i2", 1), - Val2("if false { i := 2 } else i := 3; i2 = i", "i", 1, "i2", 1), - CErr("if true { x := 2 }; x = 4", undefined), - Val2("if i := 2; true { i2 = i; i := 3 }", "i", 1, "i2", 2), - Val2("if i := 2; false {} else { i2 = i; i := 3 }", "i", 1, "i2", 2), - // Return checking - Run("fn1 := func() int { if true { return 1 } else { return 2 } }"), - Run("fn1 := func() int { if true { return 1 } else return 2 }"), - CErr("fn1 := func() int { if true { return 1 } else { } }", "return"), - CErr("fn1 := func() int { if true { } else { return 1 } }", "return"), - CErr("fn1 := func() int { if true { } else return 1 }", "return"), - CErr("fn1 := func() int { if true { } else { } }", "return"), - CErr("fn1 := func() int { if true { return 1 } }", "return"), - CErr("fn1 := func() int { if true { } }", "return"), - Run("fn1 := func() int { if true { }; return 1 }"), - CErr("fn1 := func() int { if true { } }", "return"), - CErr("fn1 := func() int { if true { } else { return 2 } }", "return"), - Run("fn1 := func() int { if true { return 1 }; return 0 }"), - Run("fn1 := func() int { if true { return 1 } else { }; return 0 }"), - Run("fn1 := func() int { if true { return 1 } else { }; return 0 }"), - - // Switch - Val1("switch { case false: i += 2; case true: i += 4; default: i += 8 }", "i", 1+4), - Val1("switch { default: i += 2; case false: i += 4; case true: i += 8 }", "i", 1+8), - CErr("switch { default: i += 2; default: i += 4 }", "more than one"), - Val1("switch false { case false: i += 2; case true: i += 4; default: i += 8 }", "i", 1+2), - CErr("switch s { case 1: }", opTypes), - CErr("switch ai { case ai: i += 2 }", opTypes), - Val1("switch 1.0 { case 1: i += 2; case 2: i += 4 }", "i", 1+2), - Val1("switch 1.5 { case 1: i += 2; case 2: i += 4 }", "i", 1), - CErr("switch oneTwo() {}", "multi-valued expression"), - Val1("switch 2 { case 1: i += 2; fallthrough; case 2: i += 4; fallthrough; case 3: i += 8; fallthrough }", "i", 1+4+8), - Val1("switch 5 { case 1: i += 2; fallthrough; default: i += 4; fallthrough; case 2: i += 8; fallthrough; case 3: i += 16; fallthrough }", "i", 1+4+8+16), - CErr("switch { case true: fallthrough; i += 2 }", "final statement"), - Val1("switch { case true: i += 2; fallthrough; ; ; case false: i += 4 }", "i", 1+2+4), - Val1("switch 2 { case 0, 1: i += 2; case 2, 3: i += 4 }", "i", 1+4), - Val2("switch func()int{i2++;return 5}() { case 1, 2: i += 2; case 4, 5: i += 4 }", "i", 1+4, "i2", 3), - Run("switch i { case i: }"), - // TODO(austin) Why doesn't this fail? - //CErr("case 1:", "XXX"), - - // For - Val2("for x := 1; x < 5; x++ { i+=x }; i2 = 4", "i", 11, "i2", 4), - Val2("for x := 1; x < 5; x++ { i+=x; break; i++ }; i2 = 4", "i", 2, "i2", 4), - Val2("for x := 1; x < 5; x++ { i+=x; continue; i++ }; i2 = 4", "i", 11, "i2", 4), - Val2("for i = 2; false; i = 3 { i = 4 }; i2 = 4", "i", 2, "i2", 4), - Val2("for i < 5 { i++ }; i2 = 4", "i", 5, "i2", 4), - Val2("for i < 0 { i++ }; i2 = 4", "i", 1, "i2", 4), - // Scoping - Val2("for i := 2; true; { i2 = i; i := 3; break }", "i", 1, "i2", 2), - // Labeled break/continue - Val1("L1: for { L2: for { i+=2; break L1; i+=4 }; i+=8 }", "i", 1+2), - Val1("L1: for { L2: for { i+=2; break L2; i+=4 }; i+=8; break; i+=16 }", "i", 1+2+8), - CErr("L1: { for { break L1 } }", "break.*not defined"), - CErr("L1: for {}; for { break L1 }", "break.*not defined"), - CErr("L1:; for { break L1 }", "break.*not defined"), - Val2("L1: for i = 0; i < 2; i++ { L2: for { i2++; continue L1; i2++ } }", "i", 2, "i2", 4), - CErr("L1: { for { continue L1 } }", "continue.*not defined"), - CErr("L1:; for { continue L1 }", "continue.*not defined"), - // Return checking - Run("fn1 := func() int{ for {} }"), - CErr("fn1 := func() int{ for true {} }", "return"), - CErr("fn1 := func() int{ for true {return 1} }", "return"), - CErr("fn1 := func() int{ for {break} }", "return"), - Run("fn1 := func() int{ for { for {break} } }"), - CErr("fn1 := func() int{ L1: for { for {break L1} } }", "return"), - Run("fn1 := func() int{ for true {}; return 1 }"), - - // Selectors - Val1("var x struct { a int; b int }; x.a = 42; i = x.a", "i", 42), - Val1("type T struct { x int }; var y struct { T }; y.x = 42; i = y.x", "i", 42), - Val2("type T struct { x int }; var y struct { T; x int }; y.x = 42; i = y.x; i2 = y.T.x", "i", 42, "i2", 0), - Run("type T struct { x int }; var y struct { *T }; a := func(){i=y.x}"), - CErr("type T struct { x int }; var x T; x.y = 42", "no field"), - CErr("type T struct { x int }; type U struct { x int }; var y struct { T; U }; y.x = 42", "ambiguous.*\tT\\.x\n\tU\\.x"), - CErr("type T struct { *T }; var x T; x.foo", "no field"), - - Val1("fib := func(int) int{return 0;}; fib = func(v int) int { if v < 2 { return 1 }; return fib(v-1)+fib(v-2) }; i = fib(20)", "i", 10946), - - // Make slice - Val2("x := make([]int, 2); x[0] = 42; i, i2 = x[0], x[1]", "i", 42, "i2", 0), - Val2("x := make([]int, 2); x[1] = 42; i, i2 = x[0], x[1]", "i", 0, "i2", 42), - RErr("x := make([]int, 2); x[-i] = 42", "negative index"), - RErr("x := make([]int, 2); x[2] = 42", "index 2 exceeds"), - Val2("x := make([]int, 2, 3); i, i2 = len(x), cap(x)", "i", 2, "i2", 3), - Val2("x := make([]int, 3, 2); i, i2 = len(x), cap(x)", "i", 3, "i2", 3), - RErr("x := make([]int, -i)", "negative length"), - RErr("x := make([]int, 2, -i)", "negative capacity"), - RErr("x := make([]int, 2, 3); x[2] = 42", "index 2 exceeds"), - CErr("x := make([]int, 2, 3, 4)", "too many"), - CErr("x := make([]int)", "not enough"), - - // TODO(austin) Test make map - - // Maps - Val1("x := make(map[int] int); x[1] = 42; i = x[1]", "i", 42), - Val2("x := make(map[int] int); x[1] = 42; i, y := x[1]", "i", 42, "y", true), - Val2("x := make(map[int] int); x[1] = 42; i, y := x[2]", "i", 0, "y", false), - // Not implemented - //Val1("x := make(map[int] int); x[1] = 42, true; i = x[1]", "i", 42), - //Val2("x := make(map[int] int); x[1] = 42; x[1] = 42, false; i, y := x[1]", "i", 0, "y", false), - Run("var x int; a := make(map[int] int); a[0], x = 1, 2"), - CErr("x := make(map[int] int); (func(a,b int){})(x[0])", "not enough"), - CErr("x := make(map[int] int); x[1] = oneTwo()", "too many"), - RErr("x := make(map[int] int); i = x[1]", "key '1' not found"), - - // Functions - Val2("func fib(n int) int { if n <= 2 { return n }; return fib(n-1) + fib(n-2) }", "fib(4)", 5, "fib(10)", 89), - Run("func f1(){}"), - Run2("func f1(){}", "f1()"), -} - -func TestStmt(t *testing.T) { runTests(t, "stmtTests", stmtTests) } diff --git a/libgo/go/exp/eval/type.go b/libgo/go/exp/eval/type.go deleted file mode 100644 index 8a93d8a6c27..00000000000 --- a/libgo/go/exp/eval/type.go +++ /dev/null @@ -1,1252 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package eval - -import ( - "big" - "go/ast" - "go/token" - "log" - "reflect" - "sort" - "unsafe" // For Sizeof -) - - -// XXX(Spec) The type compatibility section is very confusing because -// it makes it seem like there are three distinct types of -// compatibility: plain compatibility, assignment compatibility, and -// comparison compatibility. As I understand it, there's really only -// assignment compatibility and comparison and conversion have some -// restrictions and have special meaning in some cases where the types -// are not otherwise assignment compatible. The comparison -// compatibility section is almost all about the semantics of -// comparison, not the type checking of it, so it would make much more -// sense in the comparison operators section. The compatibility and -// assignment compatibility sections should be rolled into one. - -type Type interface { - // compat returns whether this type is compatible with another - // type. If conv is false, this is normal compatibility, - // where two named types are compatible only if they are the - // same named type. If conv if true, this is conversion - // compatibility, where two named types are conversion - // compatible if their definitions are conversion compatible. - // - // TODO(austin) Deal with recursive types - compat(o Type, conv bool) bool - // lit returns this type's literal. If this is a named type, - // this is the unnamed underlying type. Otherwise, this is an - // identity operation. - lit() Type - // isBoolean returns true if this is a boolean type. - isBoolean() bool - // isInteger returns true if this is an integer type. - isInteger() bool - // isFloat returns true if this is a floating type. - isFloat() bool - // isIdeal returns true if this is an ideal int or float. - isIdeal() bool - // Zero returns a new zero value of this type. - Zero() Value - // String returns the string representation of this type. - String() string - // The position where this type was defined, if any. - Pos() token.Pos -} - -type BoundedType interface { - Type - // minVal returns the smallest value of this type. - minVal() *big.Rat - // maxVal returns the largest value of this type. - maxVal() *big.Rat -} - -var universePos = token.NoPos - -/* - * Type array maps. These are used to memoize composite types. - */ - -type typeArrayMapEntry struct { - key []Type - v interface{} - next *typeArrayMapEntry -} - -type typeArrayMap map[uintptr]*typeArrayMapEntry - -func hashTypeArray(key []Type) uintptr { - hash := uintptr(0) - for _, t := range key { - hash = hash * 33 - if t == nil { - continue - } - addr := reflect.ValueOf(t).Pointer() - hash ^= addr - } - return hash -} - -func newTypeArrayMap() typeArrayMap { return make(map[uintptr]*typeArrayMapEntry) } - -func (m typeArrayMap) Get(key []Type) interface{} { - ent, ok := m[hashTypeArray(key)] - if !ok { - return nil - } - -nextEnt: - for ; ent != nil; ent = ent.next { - if len(key) != len(ent.key) { - continue - } - for i := 0; i < len(key); i++ { - if key[i] != ent.key[i] { - continue nextEnt - } - } - // Found it - return ent.v - } - - return nil -} - -func (m typeArrayMap) Put(key []Type, v interface{}) interface{} { - hash := hashTypeArray(key) - ent := m[hash] - - new := &typeArrayMapEntry{key, v, ent} - m[hash] = new - return v -} - -/* - * Common type - */ - -type commonType struct{} - -func (commonType) isBoolean() bool { return false } - -func (commonType) isInteger() bool { return false } - -func (commonType) isFloat() bool { return false } - -func (commonType) isIdeal() bool { return false } - -func (commonType) Pos() token.Pos { return token.NoPos } - -/* - * Bool - */ - -type boolType struct { - commonType -} - -var BoolType = universe.DefineType("bool", universePos, &boolType{}) - -func (t *boolType) compat(o Type, conv bool) bool { - _, ok := o.lit().(*boolType) - return ok -} - -func (t *boolType) lit() Type { return t } - -func (t *boolType) isBoolean() bool { return true } - -func (boolType) String() string { - // Use angle brackets as a convention for printing the - // underlying, unnamed type. This should only show up in - // debug output. - return "<bool>" -} - -func (t *boolType) Zero() Value { - res := boolV(false) - return &res -} - -/* - * Uint - */ - -type uintType struct { - commonType - - // 0 for architecture-dependent types - Bits uint - // true for uintptr, false for all others - Ptr bool - name string -} - -var ( - Uint8Type = universe.DefineType("uint8", universePos, &uintType{commonType{}, 8, false, "uint8"}) - Uint16Type = universe.DefineType("uint16", universePos, &uintType{commonType{}, 16, false, "uint16"}) - Uint32Type = universe.DefineType("uint32", universePos, &uintType{commonType{}, 32, false, "uint32"}) - Uint64Type = universe.DefineType("uint64", universePos, &uintType{commonType{}, 64, false, "uint64"}) - - UintType = universe.DefineType("uint", universePos, &uintType{commonType{}, 0, false, "uint"}) - UintptrType = universe.DefineType("uintptr", universePos, &uintType{commonType{}, 0, true, "uintptr"}) -) - -func (t *uintType) compat(o Type, conv bool) bool { - t2, ok := o.lit().(*uintType) - return ok && t == t2 -} - -func (t *uintType) lit() Type { return t } - -func (t *uintType) isInteger() bool { return true } - -func (t *uintType) String() string { return "<" + t.name + ">" } - -func (t *uintType) Zero() Value { - switch t.Bits { - case 0: - if t.Ptr { - res := uintptrV(0) - return &res - } else { - res := uintV(0) - return &res - } - case 8: - res := uint8V(0) - return &res - case 16: - res := uint16V(0) - return &res - case 32: - res := uint32V(0) - return &res - case 64: - res := uint64V(0) - return &res - } - panic("unexpected uint bit count") -} - -func (t *uintType) minVal() *big.Rat { return big.NewRat(0, 1) } - -func (t *uintType) maxVal() *big.Rat { - bits := t.Bits - if bits == 0 { - if t.Ptr { - bits = uint(8 * unsafe.Sizeof(uintptr(0))) - } else { - bits = uint(8 * unsafe.Sizeof(uint(0))) - } - } - numer := big.NewInt(1) - numer.Lsh(numer, bits) - numer.Sub(numer, idealOne) - return new(big.Rat).SetInt(numer) -} - -/* - * Int - */ - -type intType struct { - commonType - - // XXX(Spec) Numeric types: "There is also a set of - // architecture-independent basic numeric types whose size - // depends on the architecture." Should that be - // architecture-dependent? - - // 0 for architecture-dependent types - Bits uint - name string -} - -var ( - Int8Type = universe.DefineType("int8", universePos, &intType{commonType{}, 8, "int8"}) - Int16Type = universe.DefineType("int16", universePos, &intType{commonType{}, 16, "int16"}) - Int32Type = universe.DefineType("int32", universePos, &intType{commonType{}, 32, "int32"}) - Int64Type = universe.DefineType("int64", universePos, &intType{commonType{}, 64, "int64"}) - - IntType = universe.DefineType("int", universePos, &intType{commonType{}, 0, "int"}) -) - -func (t *intType) compat(o Type, conv bool) bool { - t2, ok := o.lit().(*intType) - return ok && t == t2 -} - -func (t *intType) lit() Type { return t } - -func (t *intType) isInteger() bool { return true } - -func (t *intType) String() string { return "<" + t.name + ">" } - -func (t *intType) Zero() Value { - switch t.Bits { - case 8: - res := int8V(0) - return &res - case 16: - res := int16V(0) - return &res - case 32: - res := int32V(0) - return &res - case 64: - res := int64V(0) - return &res - - case 0: - res := intV(0) - return &res - } - panic("unexpected int bit count") -} - -func (t *intType) minVal() *big.Rat { - bits := t.Bits - if bits == 0 { - bits = uint(8 * unsafe.Sizeof(int(0))) - } - numer := big.NewInt(-1) - numer.Lsh(numer, bits-1) - return new(big.Rat).SetInt(numer) -} - -func (t *intType) maxVal() *big.Rat { - bits := t.Bits - if bits == 0 { - bits = uint(8 * unsafe.Sizeof(int(0))) - } - numer := big.NewInt(1) - numer.Lsh(numer, bits-1) - numer.Sub(numer, idealOne) - return new(big.Rat).SetInt(numer) -} - -/* - * Ideal int - */ - -type idealIntType struct { - commonType -} - -var IdealIntType Type = &idealIntType{} - -func (t *idealIntType) compat(o Type, conv bool) bool { - _, ok := o.lit().(*idealIntType) - return ok -} - -func (t *idealIntType) lit() Type { return t } - -func (t *idealIntType) isInteger() bool { return true } - -func (t *idealIntType) isIdeal() bool { return true } - -func (t *idealIntType) String() string { return "ideal integer" } - -func (t *idealIntType) Zero() Value { return &idealIntV{idealZero} } - -/* - * Float - */ - -type floatType struct { - commonType - - // 0 for architecture-dependent type - Bits uint - - name string -} - -var ( - Float32Type = universe.DefineType("float32", universePos, &floatType{commonType{}, 32, "float32"}) - Float64Type = universe.DefineType("float64", universePos, &floatType{commonType{}, 64, "float64"}) -) - -func (t *floatType) compat(o Type, conv bool) bool { - t2, ok := o.lit().(*floatType) - return ok && t == t2 -} - -func (t *floatType) lit() Type { return t } - -func (t *floatType) isFloat() bool { return true } - -func (t *floatType) String() string { return "<" + t.name + ">" } - -func (t *floatType) Zero() Value { - switch t.Bits { - case 32: - res := float32V(0) - return &res - case 64: - res := float64V(0) - return &res - } - panic("unexpected float bit count") -} - -var maxFloat32Val *big.Rat -var maxFloat64Val *big.Rat -var minFloat32Val *big.Rat -var minFloat64Val *big.Rat - -func (t *floatType) minVal() *big.Rat { - bits := t.Bits - switch bits { - case 32: - return minFloat32Val - case 64: - return minFloat64Val - } - log.Panicf("unexpected floating point bit count: %d", bits) - panic("unreachable") -} - -func (t *floatType) maxVal() *big.Rat { - bits := t.Bits - switch bits { - case 32: - return maxFloat32Val - case 64: - return maxFloat64Val - } - log.Panicf("unexpected floating point bit count: %d", bits) - panic("unreachable") -} - -/* - * Ideal float - */ - -type idealFloatType struct { - commonType -} - -var IdealFloatType Type = &idealFloatType{} - -func (t *idealFloatType) compat(o Type, conv bool) bool { - _, ok := o.lit().(*idealFloatType) - return ok -} - -func (t *idealFloatType) lit() Type { return t } - -func (t *idealFloatType) isFloat() bool { return true } - -func (t *idealFloatType) isIdeal() bool { return true } - -func (t *idealFloatType) String() string { return "ideal float" } - -func (t *idealFloatType) Zero() Value { return &idealFloatV{big.NewRat(0, 1)} } - -/* - * String - */ - -type stringType struct { - commonType -} - -var StringType = universe.DefineType("string", universePos, &stringType{}) - -func (t *stringType) compat(o Type, conv bool) bool { - _, ok := o.lit().(*stringType) - return ok -} - -func (t *stringType) lit() Type { return t } - -func (t *stringType) String() string { return "<string>" } - -func (t *stringType) Zero() Value { - res := stringV("") - return &res -} - -/* - * Array - */ - -type ArrayType struct { - commonType - Len int64 - Elem Type -} - -var arrayTypes = make(map[int64]map[Type]*ArrayType) - -// Two array types are identical if they have identical element types -// and the same array length. - -func NewArrayType(len int64, elem Type) *ArrayType { - ts, ok := arrayTypes[len] - if !ok { - ts = make(map[Type]*ArrayType) - arrayTypes[len] = ts - } - t, ok := ts[elem] - if !ok { - t = &ArrayType{commonType{}, len, elem} - ts[elem] = t - } - return t -} - -func (t *ArrayType) compat(o Type, conv bool) bool { - t2, ok := o.lit().(*ArrayType) - if !ok { - return false - } - return t.Len == t2.Len && t.Elem.compat(t2.Elem, conv) -} - -func (t *ArrayType) lit() Type { return t } - -func (t *ArrayType) String() string { return "[]" + t.Elem.String() } - -func (t *ArrayType) Zero() Value { - res := arrayV(make([]Value, t.Len)) - // TODO(austin) It's unfortunate that each element is - // separately heap allocated. We could add ZeroArray to - // everything, though that doesn't help with multidimensional - // arrays. Or we could do something unsafe. We'll have this - // same problem with structs. - for i := int64(0); i < t.Len; i++ { - res[i] = t.Elem.Zero() - } - return &res -} - -/* - * Struct - */ - -type StructField struct { - Name string - Type Type - Anonymous bool -} - -type StructType struct { - commonType - Elems []StructField -} - -var structTypes = newTypeArrayMap() - -// Two struct types are identical if they have the same sequence of -// fields, and if corresponding fields have the same names and -// identical types. Two anonymous fields are considered to have the -// same name. - -func NewStructType(fields []StructField) *StructType { - // Start by looking up just the types - fts := make([]Type, len(fields)) - for i, f := range fields { - fts[i] = f.Type - } - tMapI := structTypes.Get(fts) - if tMapI == nil { - tMapI = structTypes.Put(fts, make(map[string]*StructType)) - } - tMap := tMapI.(map[string]*StructType) - - // Construct key for field names - key := "" - for _, f := range fields { - // XXX(Spec) It's not clear if struct { T } and struct - // { T T } are either identical or compatible. The - // "Struct Types" section says that the name of that - // field is "T", which suggests that they are - // identical, but it really means that it's the name - // for the purpose of selector expressions and nothing - // else. We decided that they should be neither - // identical or compatible. - if f.Anonymous { - key += "!" - } - key += f.Name + " " - } - - // XXX(Spec) Do the tags also have to be identical for the - // types to be identical? I certainly hope so, because - // otherwise, this is the only case where two distinct type - // objects can represent identical types. - - t, ok := tMap[key] - if !ok { - // Create new struct type - t = &StructType{commonType{}, fields} - tMap[key] = t - } - return t -} - -func (t *StructType) compat(o Type, conv bool) bool { - t2, ok := o.lit().(*StructType) - if !ok { - return false - } - if len(t.Elems) != len(t2.Elems) { - return false - } - for i, e := range t.Elems { - e2 := t2.Elems[i] - // XXX(Spec) An anonymous and a non-anonymous field - // are neither identical nor compatible. - if e.Anonymous != e2.Anonymous || - (!e.Anonymous && e.Name != e2.Name) || - !e.Type.compat(e2.Type, conv) { - return false - } - } - return true -} - -func (t *StructType) lit() Type { return t } - -func (t *StructType) String() string { - s := "struct {" - for i, f := range t.Elems { - if i > 0 { - s += "; " - } - if !f.Anonymous { - s += f.Name + " " - } - s += f.Type.String() - } - return s + "}" -} - -func (t *StructType) Zero() Value { - res := structV(make([]Value, len(t.Elems))) - for i, f := range t.Elems { - res[i] = f.Type.Zero() - } - return &res -} - -/* - * Pointer - */ - -type PtrType struct { - commonType - Elem Type -} - -var ptrTypes = make(map[Type]*PtrType) - -// Two pointer types are identical if they have identical base types. - -func NewPtrType(elem Type) *PtrType { - t, ok := ptrTypes[elem] - if !ok { - t = &PtrType{commonType{}, elem} - ptrTypes[elem] = t - } - return t -} - -func (t *PtrType) compat(o Type, conv bool) bool { - t2, ok := o.lit().(*PtrType) - if !ok { - return false - } - return t.Elem.compat(t2.Elem, conv) -} - -func (t *PtrType) lit() Type { return t } - -func (t *PtrType) String() string { return "*" + t.Elem.String() } - -func (t *PtrType) Zero() Value { return &ptrV{nil} } - -/* - * Function - */ - -type FuncType struct { - commonType - // TODO(austin) Separate receiver Type for methods? - In []Type - Variadic bool - Out []Type - builtin string -} - -var funcTypes = newTypeArrayMap() -var variadicFuncTypes = newTypeArrayMap() - -// Create singleton function types for magic built-in functions -var ( - capType = &FuncType{builtin: "cap"} - closeType = &FuncType{builtin: "close"} - closedType = &FuncType{builtin: "closed"} - lenType = &FuncType{builtin: "len"} - makeType = &FuncType{builtin: "make"} - newType = &FuncType{builtin: "new"} - panicType = &FuncType{builtin: "panic"} - printType = &FuncType{builtin: "print"} - printlnType = &FuncType{builtin: "println"} - copyType = &FuncType{builtin: "copy"} -) - -// Two function types are identical if they have the same number of -// parameters and result values and if corresponding parameter and -// result types are identical. All "..." parameters have identical -// type. Parameter and result names are not required to match. - -func NewFuncType(in []Type, variadic bool, out []Type) *FuncType { - inMap := funcTypes - if variadic { - inMap = variadicFuncTypes - } - - outMapI := inMap.Get(in) - if outMapI == nil { - outMapI = inMap.Put(in, newTypeArrayMap()) - } - outMap := outMapI.(typeArrayMap) - - tI := outMap.Get(out) - if tI != nil { - return tI.(*FuncType) - } - - t := &FuncType{commonType{}, in, variadic, out, ""} - outMap.Put(out, t) - return t -} - -func (t *FuncType) compat(o Type, conv bool) bool { - t2, ok := o.lit().(*FuncType) - if !ok { - return false - } - if len(t.In) != len(t2.In) || t.Variadic != t2.Variadic || len(t.Out) != len(t2.Out) { - return false - } - for i := range t.In { - if !t.In[i].compat(t2.In[i], conv) { - return false - } - } - for i := range t.Out { - if !t.Out[i].compat(t2.Out[i], conv) { - return false - } - } - return true -} - -func (t *FuncType) lit() Type { return t } - -func typeListString(ts []Type, ns []*ast.Ident) string { - s := "" - for i, t := range ts { - if i > 0 { - s += ", " - } - if ns != nil && ns[i] != nil { - s += ns[i].Name + " " - } - if t == nil { - // Some places use nil types to represent errors - s += "<none>" - } else { - s += t.String() - } - } - return s -} - -func (t *FuncType) String() string { - if t.builtin != "" { - return "built-in function " + t.builtin - } - args := typeListString(t.In, nil) - if t.Variadic { - if len(args) > 0 { - args += ", " - } - args += "..." - } - s := "func(" + args + ")" - if len(t.Out) > 0 { - s += " (" + typeListString(t.Out, nil) + ")" - } - return s -} - -func (t *FuncType) Zero() Value { return &funcV{nil} } - -type FuncDecl struct { - Type *FuncType - Name *ast.Ident // nil for function literals - // InNames will be one longer than Type.In if this function is - // variadic. - InNames []*ast.Ident - OutNames []*ast.Ident -} - -func (t *FuncDecl) String() string { - s := "func" - if t.Name != nil { - s += " " + t.Name.Name - } - s += funcTypeString(t.Type, t.InNames, t.OutNames) - return s -} - -func funcTypeString(ft *FuncType, ins []*ast.Ident, outs []*ast.Ident) string { - s := "(" - s += typeListString(ft.In, ins) - if ft.Variadic { - if len(ft.In) > 0 { - s += ", " - } - s += "..." - } - s += ")" - if len(ft.Out) > 0 { - s += " (" + typeListString(ft.Out, outs) + ")" - } - return s -} - -/* - * Interface - */ - -// TODO(austin) Interface values, types, and type compilation are -// implemented, but none of the type checking or semantics of -// interfaces are. - -type InterfaceType struct { - commonType - // TODO(austin) This should be a map from names to - // *FuncType's. We only need the sorted list for generating - // the type map key. It's detrimental for everything else. - methods []IMethod -} - -type IMethod struct { - Name string - Type *FuncType -} - -var interfaceTypes = newTypeArrayMap() - -func NewInterfaceType(methods []IMethod, embeds []*InterfaceType) *InterfaceType { - // Count methods of embedded interfaces - nMethods := len(methods) - for _, e := range embeds { - nMethods += len(e.methods) - } - - // Combine methods - allMethods := make([]IMethod, nMethods) - copy(allMethods, methods) - n := len(methods) - for _, e := range embeds { - for _, m := range e.methods { - allMethods[n] = m - n++ - } - } - - // Sort methods - sort.Sort(iMethodSorter(allMethods)) - - mts := make([]Type, len(allMethods)) - for i, m := range methods { - mts[i] = m.Type - } - tMapI := interfaceTypes.Get(mts) - if tMapI == nil { - tMapI = interfaceTypes.Put(mts, make(map[string]*InterfaceType)) - } - tMap := tMapI.(map[string]*InterfaceType) - - key := "" - for _, m := range allMethods { - key += m.Name + " " - } - - t, ok := tMap[key] - if !ok { - t = &InterfaceType{commonType{}, allMethods} - tMap[key] = t - } - return t -} - -type iMethodSorter []IMethod - -func (s iMethodSorter) Less(a, b int) bool { return s[a].Name < s[b].Name } - -func (s iMethodSorter) Swap(a, b int) { s[a], s[b] = s[b], s[a] } - -func (s iMethodSorter) Len() int { return len(s) } - -func (t *InterfaceType) compat(o Type, conv bool) bool { - t2, ok := o.lit().(*InterfaceType) - if !ok { - return false - } - if len(t.methods) != len(t2.methods) { - return false - } - for i, e := range t.methods { - e2 := t2.methods[i] - if e.Name != e2.Name || !e.Type.compat(e2.Type, conv) { - return false - } - } - return true -} - -func (t *InterfaceType) lit() Type { return t } - -func (t *InterfaceType) String() string { - // TODO(austin) Instead of showing embedded interfaces, this - // shows their methods. - s := "interface {" - for i, m := range t.methods { - if i > 0 { - s += "; " - } - s += m.Name + funcTypeString(m.Type, nil, nil) - } - return s + "}" -} - -// implementedBy tests if o implements t, returning nil, true if it does. -// Otherwise, it returns a method of t that o is missing and false. -func (t *InterfaceType) implementedBy(o Type) (*IMethod, bool) { - if len(t.methods) == 0 { - return nil, true - } - - // The methods of a named interface types are those of the - // underlying type. - if it, ok := o.lit().(*InterfaceType); ok { - o = it - } - - // XXX(Spec) Interface types: "A type implements any interface - // comprising any subset of its methods" It's unclear if - // methods must have identical or compatible types. 6g - // requires identical types. - - switch o := o.(type) { - case *NamedType: - for _, tm := range t.methods { - sm, ok := o.methods[tm.Name] - if !ok || sm.decl.Type != tm.Type { - return &tm, false - } - } - return nil, true - - case *InterfaceType: - var ti, oi int - for ti < len(t.methods) && oi < len(o.methods) { - tm, om := &t.methods[ti], &o.methods[oi] - switch { - case tm.Name == om.Name: - if tm.Type != om.Type { - return tm, false - } - ti++ - oi++ - case tm.Name > om.Name: - oi++ - default: - return tm, false - } - } - if ti < len(t.methods) { - return &t.methods[ti], false - } - return nil, true - } - - return &t.methods[0], false -} - -func (t *InterfaceType) Zero() Value { return &interfaceV{} } - -/* - * Slice - */ - -type SliceType struct { - commonType - Elem Type -} - -var sliceTypes = make(map[Type]*SliceType) - -// Two slice types are identical if they have identical element types. - -func NewSliceType(elem Type) *SliceType { - t, ok := sliceTypes[elem] - if !ok { - t = &SliceType{commonType{}, elem} - sliceTypes[elem] = t - } - return t -} - -func (t *SliceType) compat(o Type, conv bool) bool { - t2, ok := o.lit().(*SliceType) - if !ok { - return false - } - return t.Elem.compat(t2.Elem, conv) -} - -func (t *SliceType) lit() Type { return t } - -func (t *SliceType) String() string { return "[]" + t.Elem.String() } - -func (t *SliceType) Zero() Value { - // The value of an uninitialized slice is nil. The length and - // capacity of a nil slice are 0. - return &sliceV{Slice{nil, 0, 0}} -} - -/* - * Map type - */ - -type MapType struct { - commonType - Key Type - Elem Type -} - -var mapTypes = make(map[Type]map[Type]*MapType) - -func NewMapType(key Type, elem Type) *MapType { - ts, ok := mapTypes[key] - if !ok { - ts = make(map[Type]*MapType) - mapTypes[key] = ts - } - t, ok := ts[elem] - if !ok { - t = &MapType{commonType{}, key, elem} - ts[elem] = t - } - return t -} - -func (t *MapType) compat(o Type, conv bool) bool { - t2, ok := o.lit().(*MapType) - if !ok { - return false - } - return t.Elem.compat(t2.Elem, conv) && t.Key.compat(t2.Key, conv) -} - -func (t *MapType) lit() Type { return t } - -func (t *MapType) String() string { return "map[" + t.Key.String() + "] " + t.Elem.String() } - -func (t *MapType) Zero() Value { - // The value of an uninitialized map is nil. - return &mapV{nil} -} - -/* -type ChanType struct { - // TODO(austin) -} -*/ - -/* - * Named types - */ - -type Method struct { - decl *FuncDecl - fn Func -} - -type NamedType struct { - NamePos token.Pos - Name string - // Underlying type. If incomplete is true, this will be nil. - // If incomplete is false and this is still nil, then this is - // a placeholder type representing an error. - Def Type - // True while this type is being defined. - incomplete bool - methods map[string]Method -} - -// TODO(austin) This is temporarily needed by the debugger's remote -// type parser. This should only be possible with block.DefineType. -func NewNamedType(name string) *NamedType { - return &NamedType{token.NoPos, name, nil, true, make(map[string]Method)} -} - -func (t *NamedType) Pos() token.Pos { - return t.NamePos -} - -func (t *NamedType) Complete(def Type) { - if !t.incomplete { - log.Panicf("cannot complete already completed NamedType %+v", *t) - } - // We strip the name from def because multiple levels of - // naming are useless. - if ndef, ok := def.(*NamedType); ok { - def = ndef.Def - } - t.Def = def - t.incomplete = false -} - -func (t *NamedType) compat(o Type, conv bool) bool { - t2, ok := o.(*NamedType) - if ok { - if conv { - // Two named types are conversion compatible - // if their literals are conversion - // compatible. - return t.Def.compat(t2.Def, conv) - } else { - // Two named types are compatible if their - // type names originate in the same type - // declaration. - return t == t2 - } - } - // A named and an unnamed type are compatible if the - // respective type literals are compatible. - return o.compat(t.Def, conv) -} - -func (t *NamedType) lit() Type { return t.Def.lit() } - -func (t *NamedType) isBoolean() bool { return t.Def.isBoolean() } - -func (t *NamedType) isInteger() bool { return t.Def.isInteger() } - -func (t *NamedType) isFloat() bool { return t.Def.isFloat() } - -func (t *NamedType) isIdeal() bool { return false } - -func (t *NamedType) String() string { return t.Name } - -func (t *NamedType) Zero() Value { return t.Def.Zero() } - -/* - * Multi-valued type - */ - -// MultiType is a special type used for multi-valued expressions, akin -// to a tuple type. It's not generally accessible within the -// language. -type MultiType struct { - commonType - Elems []Type -} - -var multiTypes = newTypeArrayMap() - -func NewMultiType(elems []Type) *MultiType { - if t := multiTypes.Get(elems); t != nil { - return t.(*MultiType) - } - - t := &MultiType{commonType{}, elems} - multiTypes.Put(elems, t) - return t -} - -func (t *MultiType) compat(o Type, conv bool) bool { - t2, ok := o.lit().(*MultiType) - if !ok { - return false - } - if len(t.Elems) != len(t2.Elems) { - return false - } - for i := range t.Elems { - if !t.Elems[i].compat(t2.Elems[i], conv) { - return false - } - } - return true -} - -var EmptyType Type = NewMultiType([]Type{}) - -func (t *MultiType) lit() Type { return t } - -func (t *MultiType) String() string { - if len(t.Elems) == 0 { - return "<none>" - } - return typeListString(t.Elems, nil) -} - -func (t *MultiType) Zero() Value { - res := make([]Value, len(t.Elems)) - for i, t := range t.Elems { - res[i] = t.Zero() - } - return multiV(res) -} - -/* - * Initialize the universe - */ - -func init() { - numer := big.NewInt(0xffffff) - numer.Lsh(numer, 127-23) - maxFloat32Val = new(big.Rat).SetInt(numer) - numer.SetInt64(0x1fffffffffffff) - numer.Lsh(numer, 1023-52) - maxFloat64Val = new(big.Rat).SetInt(numer) - minFloat32Val = new(big.Rat).Neg(maxFloat32Val) - minFloat64Val = new(big.Rat).Neg(maxFloat64Val) - - // To avoid portability issues all numeric types are distinct - // except byte, which is an alias for uint8. - - // Make byte an alias for the named type uint8. Type aliases - // are otherwise impossible in Go, so just hack it here. - universe.defs["byte"] = universe.defs["uint8"] - - // Built-in functions - universe.DefineConst("cap", universePos, capType, nil) - universe.DefineConst("close", universePos, closeType, nil) - universe.DefineConst("closed", universePos, closedType, nil) - universe.DefineConst("copy", universePos, copyType, nil) - universe.DefineConst("len", universePos, lenType, nil) - universe.DefineConst("make", universePos, makeType, nil) - universe.DefineConst("new", universePos, newType, nil) - universe.DefineConst("panic", universePos, panicType, nil) - universe.DefineConst("print", universePos, printType, nil) - universe.DefineConst("println", universePos, printlnType, nil) -} diff --git a/libgo/go/exp/eval/typec.go b/libgo/go/exp/eval/typec.go deleted file mode 100644 index de90cf66496..00000000000 --- a/libgo/go/exp/eval/typec.go +++ /dev/null @@ -1,409 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package eval - -import ( - "go/ast" - "go/token" - "log" -) - - -/* - * Type compiler - */ - -type typeCompiler struct { - *compiler - block *block - // Check to be performed after a type declaration is compiled. - // - // TODO(austin) This will probably have to change after we - // eliminate forward declarations. - lateCheck func() bool -} - -func (a *typeCompiler) compileIdent(x *ast.Ident, allowRec bool) Type { - _, _, def := a.block.Lookup(x.Name) - if def == nil { - a.diagAt(x.Pos(), "%s: undefined", x.Name) - return nil - } - switch def := def.(type) { - case *Constant: - a.diagAt(x.Pos(), "constant %v used as type", x.Name) - return nil - case *Variable: - a.diagAt(x.Pos(), "variable %v used as type", x.Name) - return nil - case *NamedType: - if !allowRec && def.incomplete { - a.diagAt(x.Pos(), "illegal recursive type") - return nil - } - if !def.incomplete && def.Def == nil { - // Placeholder type from an earlier error - return nil - } - return def - case Type: - return def - } - log.Panicf("name %s has unknown type %T", x.Name, def) - return nil -} - -func (a *typeCompiler) compileArrayType(x *ast.ArrayType, allowRec bool) Type { - // Compile element type - elem := a.compileType(x.Elt, allowRec) - - // Compile length expression - if x.Len == nil { - if elem == nil { - return nil - } - return NewSliceType(elem) - } - - if _, ok := x.Len.(*ast.Ellipsis); ok { - a.diagAt(x.Len.Pos(), "... array initailizers not implemented") - return nil - } - l, ok := a.compileArrayLen(a.block, x.Len) - if !ok { - return nil - } - if l < 0 { - a.diagAt(x.Len.Pos(), "array length must be non-negative") - return nil - } - if elem == nil { - return nil - } - - return NewArrayType(l, elem) -} - -func (a *typeCompiler) compileFields(fields *ast.FieldList, allowRec bool) ([]Type, []*ast.Ident, []token.Pos, bool) { - n := fields.NumFields() - ts := make([]Type, n) - ns := make([]*ast.Ident, n) - ps := make([]token.Pos, n) - bad := false - - if fields != nil { - i := 0 - for _, f := range fields.List { - t := a.compileType(f.Type, allowRec) - if t == nil { - bad = true - } - if f.Names == nil { - ns[i] = nil - ts[i] = t - ps[i] = f.Type.Pos() - i++ - continue - } - for _, n := range f.Names { - ns[i] = n - ts[i] = t - ps[i] = n.Pos() - i++ - } - } - } - - return ts, ns, ps, bad -} - -func (a *typeCompiler) compileStructType(x *ast.StructType, allowRec bool) Type { - ts, names, poss, bad := a.compileFields(x.Fields, allowRec) - - // XXX(Spec) The spec claims that field identifiers must be - // unique, but 6g only checks this when they are accessed. I - // think the spec is better in this regard: if I write two - // fields with the same name in the same struct type, clearly - // that's a mistake. This definition does *not* descend into - // anonymous fields, so it doesn't matter if those change. - // There's separate language in the spec about checking - // uniqueness of field names inherited from anonymous fields - // at use time. - fields := make([]StructField, len(ts)) - nameSet := make(map[string]token.Pos, len(ts)) - for i := range fields { - // Compute field name and check anonymous fields - var name string - if names[i] != nil { - name = names[i].Name - } else { - if ts[i] == nil { - continue - } - - var nt *NamedType - // [For anonymous fields,] the unqualified - // type name acts as the field identifier. - switch t := ts[i].(type) { - case *NamedType: - name = t.Name - nt = t - case *PtrType: - switch t := t.Elem.(type) { - case *NamedType: - name = t.Name - nt = t - } - } - // [An anonymous field] must be specified as a - // type name T or as a pointer to a type name - // *T, and T itself, may not be a pointer or - // interface type. - if nt == nil { - a.diagAt(poss[i], "embedded type must T or *T, where T is a named type") - bad = true - continue - } - // The check for embedded pointer types must - // be deferred because of things like - // type T *struct { T } - lateCheck := a.lateCheck - a.lateCheck = func() bool { - if _, ok := nt.lit().(*PtrType); ok { - a.diagAt(poss[i], "embedded type %v is a pointer type", nt) - return false - } - return lateCheck() - } - } - - // Check name uniqueness - if prev, ok := nameSet[name]; ok { - a.diagAt(poss[i], "field %s redeclared\n\tprevious declaration at %s", name, a.fset.Position(prev)) - bad = true - continue - } - nameSet[name] = poss[i] - - // Create field - fields[i].Name = name - fields[i].Type = ts[i] - fields[i].Anonymous = (names[i] == nil) - } - - if bad { - return nil - } - - return NewStructType(fields) -} - -func (a *typeCompiler) compilePtrType(x *ast.StarExpr) Type { - elem := a.compileType(x.X, true) - if elem == nil { - return nil - } - return NewPtrType(elem) -} - -func (a *typeCompiler) compileFuncType(x *ast.FuncType, allowRec bool) *FuncDecl { - // TODO(austin) Variadic function types - - // The types of parameters and results must be complete. - // - // TODO(austin) It's not clear they actually have to be complete. - in, inNames, _, inBad := a.compileFields(x.Params, allowRec) - out, outNames, _, outBad := a.compileFields(x.Results, allowRec) - - if inBad || outBad { - return nil - } - return &FuncDecl{NewFuncType(in, false, out), nil, inNames, outNames} -} - -func (a *typeCompiler) compileInterfaceType(x *ast.InterfaceType, allowRec bool) *InterfaceType { - ts, names, poss, bad := a.compileFields(x.Methods, allowRec) - - methods := make([]IMethod, len(ts)) - nameSet := make(map[string]token.Pos, len(ts)) - embeds := make([]*InterfaceType, len(ts)) - - var nm, ne int - for i := range ts { - if ts[i] == nil { - continue - } - - if names[i] != nil { - name := names[i].Name - methods[nm].Name = name - methods[nm].Type = ts[i].(*FuncType) - nm++ - if prev, ok := nameSet[name]; ok { - a.diagAt(poss[i], "method %s redeclared\n\tprevious declaration at %s", name, a.fset.Position(prev)) - bad = true - continue - } - nameSet[name] = poss[i] - } else { - // Embedded interface - it, ok := ts[i].lit().(*InterfaceType) - if !ok { - a.diagAt(poss[i], "embedded type must be an interface") - bad = true - continue - } - embeds[ne] = it - ne++ - for _, m := range it.methods { - if prev, ok := nameSet[m.Name]; ok { - a.diagAt(poss[i], "method %s redeclared\n\tprevious declaration at %s", m.Name, a.fset.Position(prev)) - bad = true - continue - } - nameSet[m.Name] = poss[i] - } - } - } - - if bad { - return nil - } - - methods = methods[0:nm] - embeds = embeds[0:ne] - - return NewInterfaceType(methods, embeds) -} - -func (a *typeCompiler) compileMapType(x *ast.MapType) Type { - key := a.compileType(x.Key, true) - val := a.compileType(x.Value, true) - if key == nil || val == nil { - return nil - } - // XXX(Spec) The Map types section explicitly lists all types - // that can be map keys except for function types. - switch key.lit().(type) { - case *StructType: - a.diagAt(x.Pos(), "map key cannot be a struct type") - return nil - case *ArrayType: - a.diagAt(x.Pos(), "map key cannot be an array type") - return nil - case *SliceType: - a.diagAt(x.Pos(), "map key cannot be a slice type") - return nil - } - return NewMapType(key, val) -} - -func (a *typeCompiler) compileType(x ast.Expr, allowRec bool) Type { - switch x := x.(type) { - case *ast.BadExpr: - // Error already reported by parser - a.silentErrors++ - return nil - - case *ast.Ident: - return a.compileIdent(x, allowRec) - - case *ast.ArrayType: - return a.compileArrayType(x, allowRec) - - case *ast.StructType: - return a.compileStructType(x, allowRec) - - case *ast.StarExpr: - return a.compilePtrType(x) - - case *ast.FuncType: - fd := a.compileFuncType(x, allowRec) - if fd == nil { - return nil - } - return fd.Type - - case *ast.InterfaceType: - return a.compileInterfaceType(x, allowRec) - - case *ast.MapType: - return a.compileMapType(x) - - case *ast.ChanType: - goto notimpl - - case *ast.ParenExpr: - return a.compileType(x.X, allowRec) - - case *ast.Ellipsis: - a.diagAt(x.Pos(), "illegal use of ellipsis") - return nil - } - a.diagAt(x.Pos(), "expression used as type") - return nil - -notimpl: - a.diagAt(x.Pos(), "compileType: %T not implemented", x) - return nil -} - -/* - * Type compiler interface - */ - -func noLateCheck() bool { return true } - -func (a *compiler) compileType(b *block, typ ast.Expr) Type { - tc := &typeCompiler{a, b, noLateCheck} - t := tc.compileType(typ, false) - if !tc.lateCheck() { - t = nil - } - return t -} - -func (a *compiler) compileTypeDecl(b *block, decl *ast.GenDecl) bool { - ok := true - for _, spec := range decl.Specs { - spec := spec.(*ast.TypeSpec) - // Create incomplete type for this type - nt := b.DefineType(spec.Name.Name, spec.Name.Pos(), nil) - if nt != nil { - nt.(*NamedType).incomplete = true - } - // Compile type - tc := &typeCompiler{a, b, noLateCheck} - t := tc.compileType(spec.Type, false) - if t == nil { - // Create a placeholder type - ok = false - } - // Fill incomplete type - if nt != nil { - nt.(*NamedType).Complete(t) - } - // Perform late type checking with complete type - if !tc.lateCheck() { - ok = false - if nt != nil { - // Make the type a placeholder - nt.(*NamedType).Def = nil - } - } - } - return ok -} - -func (a *compiler) compileFuncType(b *block, typ *ast.FuncType) *FuncDecl { - tc := &typeCompiler{a, b, noLateCheck} - res := tc.compileFuncType(typ, false) - if res != nil { - if !tc.lateCheck() { - res = nil - } - } - return res -} diff --git a/libgo/go/exp/eval/value.go b/libgo/go/exp/eval/value.go deleted file mode 100644 index daa69189792..00000000000 --- a/libgo/go/exp/eval/value.go +++ /dev/null @@ -1,586 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package eval - -import ( - "big" - "fmt" -) - -type Value interface { - String() string - // Assign copies another value into this one. It should - // assume that the other value satisfies the same specific - // value interface (BoolValue, etc.), but must not assume - // anything about its specific type. - Assign(t *Thread, o Value) -} - -type BoolValue interface { - Value - Get(*Thread) bool - Set(*Thread, bool) -} - -type UintValue interface { - Value - Get(*Thread) uint64 - Set(*Thread, uint64) -} - -type IntValue interface { - Value - Get(*Thread) int64 - Set(*Thread, int64) -} - -// TODO(austin) IdealIntValue and IdealFloatValue should not exist -// because ideals are not l-values. -type IdealIntValue interface { - Value - Get() *big.Int -} - -type FloatValue interface { - Value - Get(*Thread) float64 - Set(*Thread, float64) -} - -type IdealFloatValue interface { - Value - Get() *big.Rat -} - -type StringValue interface { - Value - Get(*Thread) string - Set(*Thread, string) -} - -type ArrayValue interface { - Value - // TODO(austin) Get() is here for uniformity, but is - // completely useless. If a lot of other types have similarly - // useless Get methods, just special-case these uses. - Get(*Thread) ArrayValue - Elem(*Thread, int64) Value - // Sub returns an ArrayValue backed by the same array that - // starts from element i and has length len. - Sub(i int64, len int64) ArrayValue -} - -type StructValue interface { - Value - // TODO(austin) This is another useless Get() - Get(*Thread) StructValue - Field(*Thread, int) Value -} - -type PtrValue interface { - Value - Get(*Thread) Value - Set(*Thread, Value) -} - -type Func interface { - NewFrame() *Frame - Call(*Thread) -} - -type FuncValue interface { - Value - Get(*Thread) Func - Set(*Thread, Func) -} - -type Interface struct { - Type Type - Value Value -} - -type InterfaceValue interface { - Value - Get(*Thread) Interface - Set(*Thread, Interface) -} - -type Slice struct { - Base ArrayValue - Len, Cap int64 -} - -type SliceValue interface { - Value - Get(*Thread) Slice - Set(*Thread, Slice) -} - -type Map interface { - Len(*Thread) int64 - // Retrieve an element from the map, returning nil if it does - // not exist. - Elem(t *Thread, key interface{}) Value - // Set an entry in the map. If val is nil, delete the entry. - SetElem(t *Thread, key interface{}, val Value) - // TODO(austin) Perhaps there should be an iterator interface instead. - Iter(func(key interface{}, val Value) bool) -} - -type MapValue interface { - Value - Get(*Thread) Map - Set(*Thread, Map) -} - -/* - * Bool - */ - -type boolV bool - -func (v *boolV) String() string { return fmt.Sprint(*v) } - -func (v *boolV) Assign(t *Thread, o Value) { *v = boolV(o.(BoolValue).Get(t)) } - -func (v *boolV) Get(*Thread) bool { return bool(*v) } - -func (v *boolV) Set(t *Thread, x bool) { *v = boolV(x) } - -/* - * Uint - */ - -type uint8V uint8 - -func (v *uint8V) String() string { return fmt.Sprint(*v) } - -func (v *uint8V) Assign(t *Thread, o Value) { *v = uint8V(o.(UintValue).Get(t)) } - -func (v *uint8V) Get(*Thread) uint64 { return uint64(*v) } - -func (v *uint8V) Set(t *Thread, x uint64) { *v = uint8V(x) } - -type uint16V uint16 - -func (v *uint16V) String() string { return fmt.Sprint(*v) } - -func (v *uint16V) Assign(t *Thread, o Value) { *v = uint16V(o.(UintValue).Get(t)) } - -func (v *uint16V) Get(*Thread) uint64 { return uint64(*v) } - -func (v *uint16V) Set(t *Thread, x uint64) { *v = uint16V(x) } - -type uint32V uint32 - -func (v *uint32V) String() string { return fmt.Sprint(*v) } - -func (v *uint32V) Assign(t *Thread, o Value) { *v = uint32V(o.(UintValue).Get(t)) } - -func (v *uint32V) Get(*Thread) uint64 { return uint64(*v) } - -func (v *uint32V) Set(t *Thread, x uint64) { *v = uint32V(x) } - -type uint64V uint64 - -func (v *uint64V) String() string { return fmt.Sprint(*v) } - -func (v *uint64V) Assign(t *Thread, o Value) { *v = uint64V(o.(UintValue).Get(t)) } - -func (v *uint64V) Get(*Thread) uint64 { return uint64(*v) } - -func (v *uint64V) Set(t *Thread, x uint64) { *v = uint64V(x) } - -type uintV uint - -func (v *uintV) String() string { return fmt.Sprint(*v) } - -func (v *uintV) Assign(t *Thread, o Value) { *v = uintV(o.(UintValue).Get(t)) } - -func (v *uintV) Get(*Thread) uint64 { return uint64(*v) } - -func (v *uintV) Set(t *Thread, x uint64) { *v = uintV(x) } - -type uintptrV uintptr - -func (v *uintptrV) String() string { return fmt.Sprint(*v) } - -func (v *uintptrV) Assign(t *Thread, o Value) { *v = uintptrV(o.(UintValue).Get(t)) } - -func (v *uintptrV) Get(*Thread) uint64 { return uint64(*v) } - -func (v *uintptrV) Set(t *Thread, x uint64) { *v = uintptrV(x) } - -/* - * Int - */ - -type int8V int8 - -func (v *int8V) String() string { return fmt.Sprint(*v) } - -func (v *int8V) Assign(t *Thread, o Value) { *v = int8V(o.(IntValue).Get(t)) } - -func (v *int8V) Get(*Thread) int64 { return int64(*v) } - -func (v *int8V) Set(t *Thread, x int64) { *v = int8V(x) } - -type int16V int16 - -func (v *int16V) String() string { return fmt.Sprint(*v) } - -func (v *int16V) Assign(t *Thread, o Value) { *v = int16V(o.(IntValue).Get(t)) } - -func (v *int16V) Get(*Thread) int64 { return int64(*v) } - -func (v *int16V) Set(t *Thread, x int64) { *v = int16V(x) } - -type int32V int32 - -func (v *int32V) String() string { return fmt.Sprint(*v) } - -func (v *int32V) Assign(t *Thread, o Value) { *v = int32V(o.(IntValue).Get(t)) } - -func (v *int32V) Get(*Thread) int64 { return int64(*v) } - -func (v *int32V) Set(t *Thread, x int64) { *v = int32V(x) } - -type int64V int64 - -func (v *int64V) String() string { return fmt.Sprint(*v) } - -func (v *int64V) Assign(t *Thread, o Value) { *v = int64V(o.(IntValue).Get(t)) } - -func (v *int64V) Get(*Thread) int64 { return int64(*v) } - -func (v *int64V) Set(t *Thread, x int64) { *v = int64V(x) } - -type intV int - -func (v *intV) String() string { return fmt.Sprint(*v) } - -func (v *intV) Assign(t *Thread, o Value) { *v = intV(o.(IntValue).Get(t)) } - -func (v *intV) Get(*Thread) int64 { return int64(*v) } - -func (v *intV) Set(t *Thread, x int64) { *v = intV(x) } - -/* - * Ideal int - */ - -type idealIntV struct { - V *big.Int -} - -func (v *idealIntV) String() string { return v.V.String() } - -func (v *idealIntV) Assign(t *Thread, o Value) { - v.V = o.(IdealIntValue).Get() -} - -func (v *idealIntV) Get() *big.Int { return v.V } - -/* - * Float - */ - -type float32V float32 - -func (v *float32V) String() string { return fmt.Sprint(*v) } - -func (v *float32V) Assign(t *Thread, o Value) { *v = float32V(o.(FloatValue).Get(t)) } - -func (v *float32V) Get(*Thread) float64 { return float64(*v) } - -func (v *float32V) Set(t *Thread, x float64) { *v = float32V(x) } - -type float64V float64 - -func (v *float64V) String() string { return fmt.Sprint(*v) } - -func (v *float64V) Assign(t *Thread, o Value) { *v = float64V(o.(FloatValue).Get(t)) } - -func (v *float64V) Get(*Thread) float64 { return float64(*v) } - -func (v *float64V) Set(t *Thread, x float64) { *v = float64V(x) } - -/* - * Ideal float - */ - -type idealFloatV struct { - V *big.Rat -} - -func (v *idealFloatV) String() string { return v.V.FloatString(6) } - -func (v *idealFloatV) Assign(t *Thread, o Value) { - v.V = o.(IdealFloatValue).Get() -} - -func (v *idealFloatV) Get() *big.Rat { return v.V } - -/* - * String - */ - -type stringV string - -func (v *stringV) String() string { return fmt.Sprint(*v) } - -func (v *stringV) Assign(t *Thread, o Value) { *v = stringV(o.(StringValue).Get(t)) } - -func (v *stringV) Get(*Thread) string { return string(*v) } - -func (v *stringV) Set(t *Thread, x string) { *v = stringV(x) } - -/* - * Array - */ - -type arrayV []Value - -func (v *arrayV) String() string { - res := "{" - for i, e := range *v { - if i > 0 { - res += ", " - } - res += e.String() - } - return res + "}" -} - -func (v *arrayV) Assign(t *Thread, o Value) { - oa := o.(ArrayValue) - l := int64(len(*v)) - for i := int64(0); i < l; i++ { - (*v)[i].Assign(t, oa.Elem(t, i)) - } -} - -func (v *arrayV) Get(*Thread) ArrayValue { return v } - -func (v *arrayV) Elem(t *Thread, i int64) Value { - return (*v)[i] -} - -func (v *arrayV) Sub(i int64, len int64) ArrayValue { - res := (*v)[i : i+len] - return &res -} - -/* - * Struct - */ - -type structV []Value - -// TODO(austin) Should these methods (and arrayV's) be on structV -// instead of *structV? -func (v *structV) String() string { - res := "{" - for i, v := range *v { - if i > 0 { - res += ", " - } - res += v.String() - } - return res + "}" -} - -func (v *structV) Assign(t *Thread, o Value) { - oa := o.(StructValue) - l := len(*v) - for i := 0; i < l; i++ { - (*v)[i].Assign(t, oa.Field(t, i)) - } -} - -func (v *structV) Get(*Thread) StructValue { return v } - -func (v *structV) Field(t *Thread, i int) Value { - return (*v)[i] -} - -/* - * Pointer - */ - -type ptrV struct { - // nil if the pointer is nil - target Value -} - -func (v *ptrV) String() string { - if v.target == nil { - return "<nil>" - } - return "&" + v.target.String() -} - -func (v *ptrV) Assign(t *Thread, o Value) { v.target = o.(PtrValue).Get(t) } - -func (v *ptrV) Get(*Thread) Value { return v.target } - -func (v *ptrV) Set(t *Thread, x Value) { v.target = x } - -/* - * Functions - */ - -type funcV struct { - target Func -} - -func (v *funcV) String() string { - // TODO(austin) Rob wants to see the definition - return "func {...}" -} - -func (v *funcV) Assign(t *Thread, o Value) { v.target = o.(FuncValue).Get(t) } - -func (v *funcV) Get(*Thread) Func { return v.target } - -func (v *funcV) Set(t *Thread, x Func) { v.target = x } - -/* - * Interfaces - */ - -type interfaceV struct { - Interface -} - -func (v *interfaceV) String() string { - if v.Type == nil || v.Value == nil { - return "<nil>" - } - return v.Value.String() -} - -func (v *interfaceV) Assign(t *Thread, o Value) { - v.Interface = o.(InterfaceValue).Get(t) -} - -func (v *interfaceV) Get(*Thread) Interface { return v.Interface } - -func (v *interfaceV) Set(t *Thread, x Interface) { - v.Interface = x -} - -/* - * Slices - */ - -type sliceV struct { - Slice -} - -func (v *sliceV) String() string { - if v.Base == nil { - return "<nil>" - } - return v.Base.Sub(0, v.Len).String() -} - -func (v *sliceV) Assign(t *Thread, o Value) { v.Slice = o.(SliceValue).Get(t) } - -func (v *sliceV) Get(*Thread) Slice { return v.Slice } - -func (v *sliceV) Set(t *Thread, x Slice) { v.Slice = x } - -/* - * Maps - */ - -type mapV struct { - target Map -} - -func (v *mapV) String() string { - if v.target == nil { - return "<nil>" - } - res := "map[" - i := 0 - v.target.Iter(func(key interface{}, val Value) bool { - if i > 0 { - res += ", " - } - i++ - res += fmt.Sprint(key) + ":" + val.String() - return true - }) - return res + "]" -} - -func (v *mapV) Assign(t *Thread, o Value) { v.target = o.(MapValue).Get(t) } - -func (v *mapV) Get(*Thread) Map { return v.target } - -func (v *mapV) Set(t *Thread, x Map) { v.target = x } - -type evalMap map[interface{}]Value - -func (m evalMap) Len(t *Thread) int64 { return int64(len(m)) } - -func (m evalMap) Elem(t *Thread, key interface{}) Value { - return m[key] -} - -func (m evalMap) SetElem(t *Thread, key interface{}, val Value) { - if val == nil { - m[key] = nil, false - } else { - m[key] = val - } -} - -func (m evalMap) Iter(cb func(key interface{}, val Value) bool) { - for k, v := range m { - if !cb(k, v) { - break - } - } -} - -/* - * Multi-values - */ - -type multiV []Value - -func (v multiV) String() string { - res := "(" - for i, v := range v { - if i > 0 { - res += ", " - } - res += v.String() - } - return res + ")" -} - -func (v multiV) Assign(t *Thread, o Value) { - omv := o.(multiV) - for i := range v { - v[i].Assign(t, omv[i]) - } -} - -/* - * Universal constants - */ - -func init() { - s := universe - - true := boolV(true) - s.DefineConst("true", universePos, BoolType, &true) - false := boolV(false) - s.DefineConst("false", universePos, BoolType, &false) -} diff --git a/libgo/go/exp/eval/world.go b/libgo/go/exp/eval/world.go deleted file mode 100644 index a5f6ac7e5e7..00000000000 --- a/libgo/go/exp/eval/world.go +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package eval is the beginning of an interpreter for Go. -// It can run simple Go programs but does not implement -// interface values or packages. -package eval - -import ( - "go/ast" - "go/parser" - "go/scanner" - "go/token" - "os" -) - -type World struct { - scope *Scope - frame *Frame -} - -func NewWorld() *World { - w := new(World) - w.scope = universe.ChildScope() - w.scope.global = true // this block's vars allocate directly - return w -} - -type Code interface { - // The type of the value Run returns, or nil if Run returns nil. - Type() Type - - // Run runs the code; if the code is a single expression - // with a value, it returns the value; otherwise it returns nil. - Run() (Value, os.Error) -} - -type stmtCode struct { - w *World - code code -} - -func (w *World) CompileStmtList(fset *token.FileSet, stmts []ast.Stmt) (Code, os.Error) { - if len(stmts) == 1 { - if s, ok := stmts[0].(*ast.ExprStmt); ok { - return w.CompileExpr(fset, s.X) - } - } - errors := new(scanner.ErrorVector) - cc := &compiler{fset, errors, 0, 0} - cb := newCodeBuf() - fc := &funcCompiler{ - compiler: cc, - fnType: nil, - outVarsNamed: false, - codeBuf: cb, - flow: newFlowBuf(cb), - labels: make(map[string]*label), - } - bc := &blockCompiler{ - funcCompiler: fc, - block: w.scope.block, - } - nerr := cc.numError() - for _, stmt := range stmts { - bc.compileStmt(stmt) - } - fc.checkLabels() - if nerr != cc.numError() { - return nil, errors.GetError(scanner.Sorted) - } - return &stmtCode{w, fc.get()}, nil -} - -func (w *World) CompileDeclList(fset *token.FileSet, decls []ast.Decl) (Code, os.Error) { - stmts := make([]ast.Stmt, len(decls)) - for i, d := range decls { - stmts[i] = &ast.DeclStmt{d} - } - return w.CompileStmtList(fset, stmts) -} - -func (s *stmtCode) Type() Type { return nil } - -func (s *stmtCode) Run() (Value, os.Error) { - t := new(Thread) - t.f = s.w.scope.NewFrame(nil) - return nil, t.Try(func(t *Thread) { s.code.exec(t) }) -} - -type exprCode struct { - w *World - e *expr - eval func(Value, *Thread) -} - -func (w *World) CompileExpr(fset *token.FileSet, e ast.Expr) (Code, os.Error) { - errors := new(scanner.ErrorVector) - cc := &compiler{fset, errors, 0, 0} - - ec := cc.compileExpr(w.scope.block, false, e) - if ec == nil { - return nil, errors.GetError(scanner.Sorted) - } - var eval func(Value, *Thread) - switch t := ec.t.(type) { - case *idealIntType: - // nothing - case *idealFloatType: - // nothing - default: - if tm, ok := t.(*MultiType); ok && len(tm.Elems) == 0 { - return &stmtCode{w, code{ec.exec}}, nil - } - eval = genAssign(ec.t, ec) - } - return &exprCode{w, ec, eval}, nil -} - -func (e *exprCode) Type() Type { return e.e.t } - -func (e *exprCode) Run() (Value, os.Error) { - t := new(Thread) - t.f = e.w.scope.NewFrame(nil) - switch e.e.t.(type) { - case *idealIntType: - return &idealIntV{e.e.asIdealInt()()}, nil - case *idealFloatType: - return &idealFloatV{e.e.asIdealFloat()()}, nil - } - v := e.e.t.Zero() - eval := e.eval - err := t.Try(func(t *Thread) { eval(v, t) }) - return v, err -} - -func (w *World) Compile(fset *token.FileSet, text string) (Code, os.Error) { - stmts, err := parser.ParseStmtList(fset, "input", text) - if err == nil { - return w.CompileStmtList(fset, stmts) - } - - // Otherwise try as DeclList. - decls, err1 := parser.ParseDeclList(fset, "input", text) - if err1 == nil { - return w.CompileDeclList(fset, decls) - } - - // Have to pick an error. - // Parsing as statement list admits more forms, - // its error is more likely to be useful. - return nil, err -} - -type RedefinitionError struct { - Name string - Prev Def -} - -func (e *RedefinitionError) String() string { - res := "identifier " + e.Name + " redeclared" - pos := e.Prev.Pos() - if pos.IsValid() { - // TODO: fix this - currently this code is not reached by the tests - // need to get a file set (fset) from somewhere - //res += "; previous declaration at " + fset.Position(pos).String() - panic(0) - } - return res -} - -func (w *World) DefineConst(name string, t Type, val Value) os.Error { - _, prev := w.scope.DefineConst(name, token.NoPos, t, val) - if prev != nil { - return &RedefinitionError{name, prev} - } - return nil -} - -func (w *World) DefineVar(name string, t Type, val Value) os.Error { - v, prev := w.scope.DefineVar(name, token.NoPos, t) - if prev != nil { - return &RedefinitionError{name, prev} - } - v.Init = val - return nil -} diff --git a/libgo/go/exp/draw/event.go b/libgo/go/exp/gui/gui.go index b777d912e1d..17149918605 100644 --- a/libgo/go/exp/draw/event.go +++ b/libgo/go/exp/gui/gui.go @@ -2,17 +2,19 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package draw +// Package gui defines a basic graphical user interface programming model. +package gui import ( "image" + "image/draw" "os" ) // A Window represents a single graphics window. type Window interface { // Screen returns an editable Image for the window. - Screen() Image + Screen() draw.Image // FlushImage flushes changes made to Screen() back to screen. FlushImage() // EventChan returns a channel carrying UI events such as key presses, diff --git a/libgo/go/exp/draw/x11/auth.go b/libgo/go/exp/gui/x11/auth.go index d48936ac178..d48936ac178 100644 --- a/libgo/go/exp/draw/x11/auth.go +++ b/libgo/go/exp/gui/x11/auth.go diff --git a/libgo/go/exp/draw/x11/conn.go b/libgo/go/exp/gui/x11/conn.go index 81c67267db6..1d237816abf 100644 --- a/libgo/go/exp/draw/x11/conn.go +++ b/libgo/go/exp/gui/x11/conn.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package x11 implements an X11 backend for the exp/draw package. +// Package x11 implements an X11 backend for the exp/gui package. // // The X protocol specification is at ftp://ftp.x.org/pub/X11R7.0/doc/PDF/proto.pdf. // A summary of the wire format can be found in XCB's xproto.xml. @@ -10,8 +10,9 @@ package x11 import ( "bufio" - "exp/draw" + "exp/gui" "image" + "image/draw" "io" "log" "net" @@ -43,7 +44,7 @@ type conn struct { img *image.RGBA eventc chan interface{} - mouseState draw.MouseEvent + mouseState gui.MouseEvent buf [256]byte // General purpose scratch buffer. @@ -53,7 +54,7 @@ type conn struct { } // writeSocket runs in its own goroutine, serving both FlushImage calls -// directly from the exp/draw client and indirectly from X expose events. +// directly from the exp/gui client and indirectly from X expose events. // It paints c.img to the X server via PutImage requests. func (c *conn) writeSocket() { defer c.c.Close() @@ -84,25 +85,26 @@ func (c *conn) writeSocket() { for y := b.Min.Y; y < b.Max.Y; y++ { setU32LE(c.flushBuf0[16:20], uint32(y<<16)) - if _, err := c.w.Write(c.flushBuf0[0:24]); err != nil { + if _, err := c.w.Write(c.flushBuf0[:24]); err != nil { if err != os.EOF { log.Println("x11:", err.String()) } return } - p := c.img.Pix[y*c.img.Stride : (y+1)*c.img.Stride] - for x := b.Min.X; x < b.Max.X; { - nx := b.Max.X - x - if nx > len(c.flushBuf1)/4 { - nx = len(c.flushBuf1) / 4 + p := c.img.Pix[(y-b.Min.Y)*c.img.Stride:] + for x, dx := 0, 4*b.Dx(); x < dx; { + nx := dx - x + if nx > len(c.flushBuf1) { + nx = len(c.flushBuf1) &^ 3 } - for i, rgba := range p[x : x+nx] { - c.flushBuf1[4*i+0] = rgba.B - c.flushBuf1[4*i+1] = rgba.G - c.flushBuf1[4*i+2] = rgba.R + for i := 0; i < nx; i += 4 { + // X11's order is BGRX, not RGBA. + c.flushBuf1[i+0] = p[x+i+2] + c.flushBuf1[i+1] = p[x+i+1] + c.flushBuf1[i+2] = p[x+i+0] } x += nx - if _, err := c.w.Write(c.flushBuf1[0 : 4*nx]); err != nil { + if _, err := c.w.Write(c.flushBuf1[:nx]); err != nil { if err != os.EOF { log.Println("x11:", err.String()) } @@ -143,7 +145,7 @@ func (c *conn) Close() os.Error { func (c *conn) EventChan() <-chan interface{} { return c.eventc } -// readSocket runs in its own goroutine, reading X events and sending draw +// readSocket runs in its own goroutine, reading X events and sending gui // events on c's EventChan. func (c *conn) readSocket() { var ( @@ -153,9 +155,9 @@ func (c *conn) readSocket() { defer close(c.eventc) for { // X events are always 32 bytes long. - if _, err := io.ReadFull(c.r, c.buf[0:32]); err != nil { + if _, err := io.ReadFull(c.r, c.buf[:32]); err != nil { if err != os.EOF { - c.eventc <- draw.ErrEvent{err} + c.eventc <- gui.ErrEvent{err} } return } @@ -165,7 +167,7 @@ func (c *conn) readSocket() { if cookie != 1 { // We issued only one request (GetKeyboardMapping) with a cookie of 1, // so we shouldn't get any other reply from the X server. - c.eventc <- draw.ErrEvent{os.NewError("x11: unexpected cookie")} + c.eventc <- gui.ErrEvent{os.NewError("x11: unexpected cookie")} return } keysymsPerKeycode = int(c.buf[1]) @@ -176,10 +178,10 @@ func (c *conn) readSocket() { for i := keymapLo; i <= keymapHi; i++ { m := keymap[i] for j := range m { - u, err := readU32LE(c.r, c.buf[0:4]) + u, err := readU32LE(c.r, c.buf[:4]) if err != nil { if err != os.EOF { - c.eventc <- draw.ErrEvent{err} + c.eventc <- gui.ErrEvent{err} } return } @@ -204,11 +206,11 @@ func (c *conn) readSocket() { // TODO(nigeltao): Should we send KeyEvents for Shift/Ctrl/Alt? Should Shift-A send // the same int down the channel as the sent on just the A key? // TODO(nigeltao): How should IME events (e.g. key presses that should generate CJK text) work? Or - // is that outside the scope of the draw.Window interface? + // is that outside the scope of the gui.Window interface? if c.buf[0] == 0x03 { keysym = -keysym } - c.eventc <- draw.KeyEvent{keysym} + c.eventc <- gui.KeyEvent{keysym} case 0x04, 0x05: // Button press, button release. mask := 1 << (c.buf[1] - 1) if c.buf[0] == 0x04 { @@ -259,14 +261,14 @@ func connect(display string) (conn net.Conn, displayStr string, err os.Error) { // Parse the section before the colon. var protocol, host, socket string if display[0] == '/' { - socket = display[0:colonIdx] + socket = display[:colonIdx] } else { if i := strings.LastIndex(display, "/"); i < 0 { // The default protocol is TCP. protocol = "tcp" - host = display[0:colonIdx] + host = display[:colonIdx] } else { - protocol = display[0:i] + protocol = display[:i] host = display[i+1 : colonIdx] } } @@ -278,7 +280,7 @@ func connect(display string) (conn net.Conn, displayStr string, err os.Error) { if i := strings.LastIndex(after, "."); i < 0 { displayStr = after } else { - displayStr = after[0:i] + displayStr = after[:i] } displayInt, err := strconv.Atoi(displayStr) if err != nil || displayInt < 0 { @@ -310,7 +312,7 @@ func authenticate(w *bufio.Writer, displayStr string) os.Error { return os.NewError("unsupported Xauth") } // 0x006c means little-endian. 0x000b, 0x0000 means X major version 11, minor version 0. - // 0x0012 and 0x0010 means the auth key and value have lenths 18 and 16. + // 0x0012 and 0x0010 means the auth key and value have lengths 18 and 16. // The final 0x0000 is padding, so that the string length is a multiple of 4. _, err = io.WriteString(w, "\x6c\x00\x0b\x00\x00\x00\x12\x00\x10\x00\x00\x00") if err != nil { @@ -338,7 +340,7 @@ func authenticate(w *bufio.Writer, displayStr string) os.Error { // readU8 reads a uint8 from r, using b as a scratch buffer. func readU8(r io.Reader, b []byte) (uint8, os.Error) { - _, err := io.ReadFull(r, b[0:1]) + _, err := io.ReadFull(r, b[:1]) if err != nil { return 0, err } @@ -347,7 +349,7 @@ func readU8(r io.Reader, b []byte) (uint8, os.Error) { // readU16LE reads a little-endian uint16 from r, using b as a scratch buffer. func readU16LE(r io.Reader, b []byte) (uint16, os.Error) { - _, err := io.ReadFull(r, b[0:2]) + _, err := io.ReadFull(r, b[:2]) if err != nil { return 0, err } @@ -356,14 +358,14 @@ func readU16LE(r io.Reader, b []byte) (uint16, os.Error) { // readU32LE reads a little-endian uint32 from r, using b as a scratch buffer. func readU32LE(r io.Reader, b []byte) (uint32, os.Error) { - _, err := io.ReadFull(r, b[0:4]) + _, err := io.ReadFull(r, b[:4]) if err != nil { return 0, err } return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24, nil } -// setU32LE sets b[0:4] to be the little-endian representation of u. +// setU32LE sets b[:4] to be the little-endian representation of u. func setU32LE(b []byte, u uint32) { b[0] = byte((u >> 0) & 0xff) b[1] = byte((u >> 8) & 0xff) @@ -374,7 +376,7 @@ func setU32LE(b []byte, u uint32) { // checkPixmapFormats checks that we have an agreeable X pixmap Format. func checkPixmapFormats(r io.Reader, b []byte, n int) (agree bool, err os.Error) { for i := 0; i < n; i++ { - _, err = io.ReadFull(r, b[0:8]) + _, err = io.ReadFull(r, b[:8]) if err != nil { return } @@ -399,7 +401,7 @@ func checkDepths(r io.Reader, b []byte, n int, visual uint32) (agree bool, err o return } // Ignore 4 bytes of padding. - _, err = io.ReadFull(r, b[0:4]) + _, err = io.ReadFull(r, b[:4]) if err != nil { return } @@ -432,7 +434,7 @@ func checkScreens(r io.Reader, b []byte, n int) (root, visual uint32, err os.Err } // Ignore the next 7x4 bytes, which is: colormap, whitepixel, blackpixel, current input masks, // width and height (pixels), width and height (mm), min and max installed maps. - _, err = io.ReadFull(r, b[0:28]) + _, err = io.ReadFull(r, b[:28]) if err != nil { return } @@ -461,26 +463,26 @@ func checkScreens(r io.Reader, b []byte, n int) (root, visual uint32, err os.Err // handshake performs the protocol handshake with the X server, and ensures // that the server provides a compatible Screen, Depth, etc. func (c *conn) handshake() os.Error { - _, err := io.ReadFull(c.r, c.buf[0:8]) + _, err := io.ReadFull(c.r, c.buf[:8]) if err != nil { return err } - // Byte 0:1 should be 1 (success), bytes 2:6 should be 0xb0000000 (major/minor version 11.0). + // Byte 0 should be 1 (success), bytes 2:6 should be 0xb0000000 (major/minor version 11.0). if c.buf[0] != 1 || c.buf[2] != 11 || c.buf[3] != 0 || c.buf[4] != 0 || c.buf[5] != 0 { return os.NewError("unsupported X version") } // Ignore the release number. - _, err = io.ReadFull(c.r, c.buf[0:4]) + _, err = io.ReadFull(c.r, c.buf[:4]) if err != nil { return err } // Read the resource ID base. - resourceIdBase, err := readU32LE(c.r, c.buf[0:4]) + resourceIdBase, err := readU32LE(c.r, c.buf[:4]) if err != nil { return err } // Read the resource ID mask. - resourceIdMask, err := readU32LE(c.r, c.buf[0:4]) + resourceIdMask, err := readU32LE(c.r, c.buf[:4]) if err != nil { return err } @@ -488,19 +490,19 @@ func (c *conn) handshake() os.Error { return os.NewError("X resource ID mask is too small") } // Ignore the motion buffer size. - _, err = io.ReadFull(c.r, c.buf[0:4]) + _, err = io.ReadFull(c.r, c.buf[:4]) if err != nil { return err } // Read the vendor length and round it up to a multiple of 4, // for X11 protocol alignment reasons. - vendorLen, err := readU16LE(c.r, c.buf[0:2]) + vendorLen, err := readU16LE(c.r, c.buf[:2]) if err != nil { return err } vendorLen = (vendorLen + 3) &^ 3 // Read the maximum request length. - maxReqLen, err := readU16LE(c.r, c.buf[0:2]) + maxReqLen, err := readU16LE(c.r, c.buf[:2]) if err != nil { return err } @@ -508,27 +510,27 @@ func (c *conn) handshake() os.Error { return os.NewError("unsupported X maximum request length") } // Read the roots length. - rootsLen, err := readU8(c.r, c.buf[0:1]) + rootsLen, err := readU8(c.r, c.buf[:1]) if err != nil { return err } // Read the pixmap formats length. - pixmapFormatsLen, err := readU8(c.r, c.buf[0:1]) + pixmapFormatsLen, err := readU8(c.r, c.buf[:1]) if err != nil { return err } - // Ignore some things that we don't care about (totalling 10 + vendorLen bytes): + // Ignore some things that we don't care about (totaling 10 + vendorLen bytes): // imageByteOrder(1), bitmapFormatBitOrder(1), bitmapFormatScanlineUnit(1) bitmapFormatScanlinePad(1), // minKeycode(1), maxKeycode(1), padding(4), vendor (vendorLen). if 10+int(vendorLen) > cap(c.buf) { return os.NewError("unsupported X vendor") } - _, err = io.ReadFull(c.r, c.buf[0:10+int(vendorLen)]) + _, err = io.ReadFull(c.r, c.buf[:10+int(vendorLen)]) if err != nil { return err } // Check that we have an agreeable pixmap format. - agree, err := checkPixmapFormats(c.r, c.buf[0:8], int(pixmapFormatsLen)) + agree, err := checkPixmapFormats(c.r, c.buf[:8], int(pixmapFormatsLen)) if err != nil { return err } @@ -536,7 +538,7 @@ func (c *conn) handshake() os.Error { return os.NewError("unsupported X pixmap formats") } // Check that we have an agreeable screen. - root, visual, err := checkScreens(c.r, c.buf[0:24], int(rootsLen)) + root, visual, err := checkScreens(c.r, c.buf[:24], int(rootsLen)) if err != nil { return err } @@ -551,7 +553,7 @@ func (c *conn) handshake() os.Error { } // NewWindow calls NewWindowDisplay with $DISPLAY. -func NewWindow() (draw.Window, os.Error) { +func NewWindow() (gui.Window, os.Error) { display := os.Getenv("DISPLAY") if len(display) == 0 { return nil, os.NewError("$DISPLAY not set") @@ -559,10 +561,10 @@ func NewWindow() (draw.Window, os.Error) { return NewWindowDisplay(display) } -// NewWindowDisplay returns a new draw.Window, backed by a newly created and +// NewWindowDisplay returns a new gui.Window, backed by a newly created and // mapped X11 window. The X server to connect to is specified by the display // string, such as ":1". -func NewWindowDisplay(display string) (draw.Window, os.Error) { +func NewWindowDisplay(display string) (gui.Window, os.Error) { socket, displayStr, err := connect(display) if err != nil { return nil, err @@ -607,7 +609,7 @@ func NewWindowDisplay(display string) (draw.Window, os.Error) { setU32LE(c.buf[72:76], 0x00020008) // 0x08 is the MapWindow opcode, and the message is 2 x 4 bytes long. setU32LE(c.buf[76:80], uint32(c.window)) // Write the bytes. - _, err = c.w.Write(c.buf[0:80]) + _, err = c.w.Write(c.buf[:80]) if err != nil { return nil, err } diff --git a/libgo/go/exp/norm/composition.go b/libgo/go/exp/norm/composition.go new file mode 100644 index 00000000000..b2d2abaf63b --- /dev/null +++ b/libgo/go/exp/norm/composition.go @@ -0,0 +1,344 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package norm + +import "utf8" + +const ( + maxCombiningChars = 30 + 2 // +2 to hold CGJ and Hangul overflow. + maxBackRunes = maxCombiningChars - 1 + maxNFCExpansion = 3 // NFC(0x1D160) + maxNFKCExpansion = 18 // NFKC(0xFDFA) + + maxRuneSizeInDecomp = 4 + // Need to multiply by 2 as we don't reuse byte buffer space for recombining. + maxByteBufferSize = 2 * maxRuneSizeInDecomp * maxCombiningChars // 256 +) + +// reorderBuffer is used to normalize a single segment. Characters inserted with +// insert() are decomposed and reordered based on CCC. The compose() method can +// be used to recombine characters. Note that the byte buffer does not hold +// the UTF-8 characters in order. Only the rune array is maintained in sorted +// order. flush() writes the resulting segment to a byte array. +type reorderBuffer struct { + rune [maxCombiningChars]runeInfo // Per character info. + byte [maxByteBufferSize]byte // UTF-8 buffer. Referenced by runeInfo.pos. + nrune int // Number of runeInfos. + nbyte uint8 // Number or bytes. + f formInfo +} + +// reset discards all characters from the buffer. +func (rb *reorderBuffer) reset() { + rb.nrune = 0 + rb.nbyte = 0 +} + +// flush appends the normalized segment to out and resets rb. +func (rb *reorderBuffer) flush(out []byte) []byte { + for i := 0; i < rb.nrune; i++ { + start := rb.rune[i].pos + end := start + rb.rune[i].size + out = append(out, rb.byte[start:end]...) + } + rb.reset() + return out +} + +// insertOrdered inserts a rune in the buffer, ordered by Canonical Combining Class. +// It returns false if the buffer is not large enough to hold the rune. +// It is used internally by insert. +func (rb *reorderBuffer) insertOrdered(info runeInfo) bool { + n := rb.nrune + if n >= maxCombiningChars { + return false + } + b := rb.rune[:] + cc := info.ccc + if cc > 0 { + // Find insertion position + move elements to make room. + for ; n > 0; n-- { + if b[n-1].ccc <= cc { + break + } + b[n] = b[n-1] + } + } + rb.nrune += 1 + pos := uint8(rb.nbyte) + rb.nbyte += info.size + info.pos = pos + b[n] = info + return true +} + +// insert inserts the given rune in the buffer ordered by CCC. +// It returns true if the buffer was large enough to hold the decomposed rune. +func (rb *reorderBuffer) insert(src []byte, info runeInfo) bool { + if info.size == 3 && isHangul(src) { + rune, _ := utf8.DecodeRune(src) + return rb.decomposeHangul(uint32(rune)) + } + pos := rb.nbyte + if info.flags.hasDecomposition() { + dcomp := rb.f.decompose(src) + for i := 0; i < len(dcomp); i += int(info.size) { + info = rb.f.info(dcomp[i:]) + if !rb.insertOrdered(info) { + return false + } + } + copy(rb.byte[pos:], dcomp) + } else { + if !rb.insertOrdered(info) { + return false + } + copy(rb.byte[pos:], src[:info.size]) + } + return true +} + +// insertString inserts the given rune in the buffer ordered by CCC. +// It returns true if the buffer was large enough to hold the decomposed rune. +func (rb *reorderBuffer) insertString(src string, info runeInfo) bool { + if info.size == 3 && isHangulString(src) { + rune, _ := utf8.DecodeRuneInString(src) + return rb.decomposeHangul(uint32(rune)) + } + pos := rb.nbyte + dcomp := rb.f.decomposeString(src) + dn := len(dcomp) + if dn != 0 { + for i := 0; i < dn; i += int(info.size) { + info = rb.f.info(dcomp[i:]) + if !rb.insertOrdered(info) { + return false + } + } + copy(rb.byte[pos:], dcomp) + } else { + if !rb.insertOrdered(info) { + return false + } + copy(rb.byte[pos:], src[:info.size]) + } + return true +} + +// appendRune inserts a rune at the end of the buffer. It is used for Hangul. +func (rb *reorderBuffer) appendRune(rune uint32) { + bn := rb.nbyte + sz := utf8.EncodeRune(rb.byte[bn:], int(rune)) + rb.nbyte += uint8(sz) + rb.rune[rb.nrune] = runeInfo{bn, uint8(sz), 0, 0} + rb.nrune++ +} + +// assignRune sets a rune at position pos. It is used for Hangul and recomposition. +func (rb *reorderBuffer) assignRune(pos int, rune uint32) { + bn := rb.nbyte + sz := utf8.EncodeRune(rb.byte[bn:], int(rune)) + rb.rune[pos] = runeInfo{bn, uint8(sz), 0, 0} + rb.nbyte += uint8(sz) +} + +// runeAt returns the rune at position n. It is used for Hangul and recomposition. +func (rb *reorderBuffer) runeAt(n int) uint32 { + inf := rb.rune[n] + rune, _ := utf8.DecodeRune(rb.byte[inf.pos : inf.pos+inf.size]) + return uint32(rune) +} + +// bytesAt returns the UTF-8 encoding of the rune at position n. +// It is used for Hangul and recomposition. +func (rb *reorderBuffer) bytesAt(n int) []byte { + inf := rb.rune[n] + return rb.byte[inf.pos : int(inf.pos)+int(inf.size)] +} + +// For Hangul we combine algorithmically, instead of using tables. +const ( + hangulBase = 0xAC00 // UTF-8(hangulBase) -> EA B0 80 + hangulBase0 = 0xEA + hangulBase1 = 0xB0 + hangulBase2 = 0x80 + + hangulEnd = hangulBase + jamoLVTCount // UTF-8(0xD7A4) -> ED 9E A4 + hangulEnd0 = 0xED + hangulEnd1 = 0x9E + hangulEnd2 = 0xA4 + + jamoLBase = 0x1100 // UTF-8(jamoLBase) -> E1 84 00 + jamoLBase0 = 0xE1 + jamoLBase1 = 0x84 + jamoLEnd = 0x1113 + jamoVBase = 0x1161 + jamoVEnd = 0x1176 + jamoTBase = 0x11A7 + jamoTEnd = 0x11C3 + + jamoTCount = 28 + jamoVCount = 21 + jamoVTCount = 21 * 28 + jamoLVTCount = 19 * 21 * 28 +) + +// Caller must verify that len(b) >= 3. +func isHangul(b []byte) bool { + b0 := b[0] + if b0 < hangulBase0 { + return false + } + b1 := b[1] + switch { + case b0 == hangulBase0: + return b1 >= hangulBase1 + case b0 < hangulEnd0: + return true + case b0 > hangulEnd0: + return false + case b1 < hangulEnd1: + return true + } + return b1 == hangulEnd1 && b[2] < hangulEnd2 +} + +// Caller must verify that len(b) >= 3. +func isHangulString(b string) bool { + b0 := b[0] + if b0 < hangulBase0 { + return false + } + b1 := b[1] + switch { + case b0 == hangulBase0: + return b1 >= hangulBase1 + case b0 < hangulEnd0: + return true + case b0 > hangulEnd0: + return false + case b1 < hangulEnd1: + return true + } + return b1 == hangulEnd1 && b[2] < hangulEnd2 +} + +// Caller must ensure len(b) >= 2. +func isJamoVT(b []byte) bool { + // True if (rune & 0xff00) == jamoLBase + return b[0] == jamoLBase0 && (b[1]&0xFC) == jamoLBase1 +} + +func isHangulWithoutJamoT(b []byte) bool { + c, _ := utf8.DecodeRune(b) + c -= hangulBase + return c < jamoLVTCount && c%jamoTCount == 0 +} + +// decomposeHangul algorithmically decomposes a Hangul rune into +// its Jamo components. +// See http://unicode.org/reports/tr15/#Hangul for details on decomposing Hangul. +func (rb *reorderBuffer) decomposeHangul(rune uint32) bool { + b := rb.rune[:] + n := rb.nrune + if n+3 > len(b) { + return false + } + rune -= hangulBase + x := rune % jamoTCount + rune /= jamoTCount + rb.appendRune(jamoLBase + rune/jamoVCount) + rb.appendRune(jamoVBase + rune%jamoVCount) + if x != 0 { + rb.appendRune(jamoTBase + x) + } + return true +} + +// combineHangul algorithmically combines Jamo character components into Hangul. +// See http://unicode.org/reports/tr15/#Hangul for details on combining Hangul. +func (rb *reorderBuffer) combineHangul() { + k := 1 + b := rb.rune[:] + bn := rb.nrune + for s, i := 0, 1; i < bn; i++ { + cccB := b[k-1].ccc + cccC := b[i].ccc + if cccB == 0 { + s = k - 1 + } + if s != k-1 && cccB >= cccC { + // b[i] is blocked by greater-equal cccX below it + b[k] = b[i] + k++ + } else { + l := rb.runeAt(s) // also used to compare to hangulBase + v := rb.runeAt(i) // also used to compare to jamoT + switch { + case jamoLBase <= l && l < jamoLEnd && + jamoVBase <= v && v < jamoVEnd: + // 11xx plus 116x to LV + rb.assignRune(s, hangulBase+ + (l-jamoLBase)*jamoVTCount+(v-jamoVBase)*jamoTCount) + case hangulBase <= l && l < hangulEnd && + jamoTBase < v && v < jamoTEnd && + ((l-hangulBase)%jamoTCount) == 0: + // ACxx plus 11Ax to LVT + rb.assignRune(s, l+v-jamoTBase) + default: + b[k] = b[i] + k++ + } + } + } + rb.nrune = k +} + +// compose recombines the runes in the buffer. +// It should only be used to recompose a single segment, as it will not +// handle alternations between Hangul and non-Hangul characters correctly. +func (rb *reorderBuffer) compose() { + // UAX #15, section X5 , including Corrigendum #5 + // "In any character sequence beginning with starter S, a character C is + // blocked from S if and only if there is some character B between S + // and C, and either B is a starter or it has the same or higher + // combining class as C." + k := 1 + b := rb.rune[:] + bn := rb.nrune + for s, i := 0, 1; i < bn; i++ { + if isJamoVT(rb.bytesAt(i)) { + // Redo from start in Hangul mode. Necessary to support + // U+320E..U+321E in NFKC mode. + rb.combineHangul() + return + } + ii := b[i] + // We can only use combineForward as a filter if we later + // get the info for the combined character. This is more + // expensive than using the filter. Using combinesBackward() + // is safe. + if ii.flags.combinesBackward() { + cccB := b[k-1].ccc + cccC := ii.ccc + blocked := false // b[i] blocked by starter or greater or equal CCC? + if cccB == 0 { + s = k - 1 + } else { + blocked = s != k-1 && cccB >= cccC + } + if !blocked { + combined := combine(rb.runeAt(s), rb.runeAt(i)) + if combined != 0 { + rb.assignRune(s, combined) + continue + } + } + } + b[k] = b[i] + k++ + } + rb.nrune = k +} diff --git a/libgo/go/exp/norm/composition_test.go b/libgo/go/exp/norm/composition_test.go new file mode 100644 index 00000000000..195a0c1e8e9 --- /dev/null +++ b/libgo/go/exp/norm/composition_test.go @@ -0,0 +1,138 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package norm + +import "testing" + +// TestCase is used for most tests. +type TestCase struct { + in []int + out []int +} + +type insertFunc func(rb *reorderBuffer, rune int) bool + +func insert(rb *reorderBuffer, rune int) bool { + b := []byte(string(rune)) + return rb.insert(b, rb.f.info(b)) +} + +func insertString(rb *reorderBuffer, rune int) bool { + s := string(rune) + return rb.insertString(s, rb.f.infoString(s)) +} + +func runTests(t *testing.T, name string, rb *reorderBuffer, f insertFunc, tests []TestCase) { + for i, test := range tests { + rb.reset() + for j, rune := range test.in { + b := []byte(string(rune)) + if !rb.insert(b, rb.f.info(b)) { + t.Errorf("%s:%d: insert failed for rune %d", name, i, j) + } + } + if rb.f.composing { + rb.compose() + } + if rb.nrune != len(test.out) { + t.Errorf("%s:%d: length = %d; want %d", name, i, rb.nrune, len(test.out)) + continue + } + for j, want := range test.out { + found := int(rb.runeAt(j)) + if found != want { + t.Errorf("%s:%d: runeAt(%d) = %U; want %U", name, i, j, found, want) + } + } + } +} + +func TestFlush(t *testing.T) { + rb := &reorderBuffer{f: *formTable[NFC]} + out := make([]byte, 0) + + out = rb.flush(out) + if len(out) != 0 { + t.Errorf("wrote bytes on flush of empty buffer. (len(out) = %d)", len(out)) + } + + for _, r := range []int("world!") { + insert(rb, r) + } + + out = []byte("Hello ") + out = rb.flush(out) + want := "Hello world!" + if string(out) != want { + t.Errorf(`output after flush was "%s"; want "%s"`, string(out), want) + } + if rb.nrune != 0 { + t.Errorf("flush: non-null size of info buffer (rb.nrune == %d)", rb.nrune) + } + if rb.nbyte != 0 { + t.Errorf("flush: non-null size of byte buffer (rb.nbyte == %d)", rb.nbyte) + } +} + +var insertTests = []TestCase{ + {[]int{'a'}, []int{'a'}}, + {[]int{0x300}, []int{0x300}}, + {[]int{0x300, 0x316}, []int{0x316, 0x300}}, // CCC(0x300)==230; CCC(0x316)==220 + {[]int{0x316, 0x300}, []int{0x316, 0x300}}, + {[]int{0x41, 0x316, 0x300}, []int{0x41, 0x316, 0x300}}, + {[]int{0x41, 0x300, 0x316}, []int{0x41, 0x316, 0x300}}, + {[]int{0x300, 0x316, 0x41}, []int{0x316, 0x300, 0x41}}, + {[]int{0x41, 0x300, 0x40, 0x316}, []int{0x41, 0x300, 0x40, 0x316}}, +} + +func TestInsert(t *testing.T) { + rb := &reorderBuffer{f: *formTable[NFD]} + runTests(t, "TestInsert", rb, insert, insertTests) +} + +func TestInsertString(t *testing.T) { + rb := &reorderBuffer{f: *formTable[NFD]} + runTests(t, "TestInsertString", rb, insertString, insertTests) +} + +var decompositionNFDTest = []TestCase{ + {[]int{0xC0}, []int{0x41, 0x300}}, + {[]int{0xAC00}, []int{0x1100, 0x1161}}, + {[]int{0x01C4}, []int{0x01C4}}, + {[]int{0x320E}, []int{0x320E}}, + {[]int("음ẻ과"), []int{0x110B, 0x1173, 0x11B7, 0x65, 0x309, 0x1100, 0x116A}}, +} + +var decompositionNFKDTest = []TestCase{ + {[]int{0xC0}, []int{0x41, 0x300}}, + {[]int{0xAC00}, []int{0x1100, 0x1161}}, + {[]int{0x01C4}, []int{0x44, 0x5A, 0x030C}}, + {[]int{0x320E}, []int{0x28, 0x1100, 0x1161, 0x29}}, +} + +func TestDecomposition(t *testing.T) { + rb := &reorderBuffer{} + rb.f = *formTable[NFD] + runTests(t, "TestDecompositionNFD", rb, insert, decompositionNFDTest) + rb.f = *formTable[NFKD] + runTests(t, "TestDecompositionNFKD", rb, insert, decompositionNFKDTest) +} + +var compositionTest = []TestCase{ + {[]int{0x41, 0x300}, []int{0xC0}}, + {[]int{0x41, 0x316}, []int{0x41, 0x316}}, + {[]int{0x41, 0x300, 0x35D}, []int{0xC0, 0x35D}}, + {[]int{0x41, 0x316, 0x300}, []int{0xC0, 0x316}}, + // blocking starter + {[]int{0x41, 0x316, 0x40, 0x300}, []int{0x41, 0x316, 0x40, 0x300}}, + {[]int{0x1100, 0x1161}, []int{0xAC00}}, + // parenthesized Hangul, alternate between ASCII and Hangul. + {[]int{0x28, 0x1100, 0x1161, 0x29}, []int{0x28, 0xAC00, 0x29}}, +} + +func TestComposition(t *testing.T) { + rb := &reorderBuffer{f: *formTable[NFC]} + runTests(t, "TestComposition", rb, insert, compositionTest) +} diff --git a/libgo/go/exp/norm/forminfo.go b/libgo/go/exp/norm/forminfo.go new file mode 100644 index 00000000000..ee3edb8ea7d --- /dev/null +++ b/libgo/go/exp/norm/forminfo.go @@ -0,0 +1,188 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package norm + +// This file contains Form-specific logic and wrappers for data in tables.go. + +type runeInfo struct { + pos uint8 // start position in reorderBuffer; used in composition.go + size uint8 // length of UTF-8 encoding of this rune + ccc uint8 // canonical combining class + flags qcInfo // quick check flags +} + +// functions dispatchable per form +type boundaryFunc func(f *formInfo, info runeInfo) bool +type lookupFunc func(b []byte) runeInfo +type lookupFuncString func(s string) runeInfo +type decompFunc func(b []byte) []byte +type decompFuncString func(s string) []byte + +// formInfo holds Form-specific functions and tables. +type formInfo struct { + form Form + + composing, compatibility bool // form type + + decompose decompFunc + decomposeString decompFuncString + info lookupFunc + infoString lookupFuncString + boundaryBefore boundaryFunc + boundaryAfter boundaryFunc +} + +var formTable []*formInfo + +func init() { + formTable = make([]*formInfo, 4) + + for i := range formTable { + f := &formInfo{} + formTable[i] = f + f.form = Form(i) + if Form(i) == NFKD || Form(i) == NFKC { + f.compatibility = true + f.decompose = decomposeNFKC + f.decomposeString = decomposeStringNFKC + f.info = lookupInfoNFKC + f.infoString = lookupInfoStringNFKC + } else { + f.decompose = decomposeNFC + f.decomposeString = decomposeStringNFC + f.info = lookupInfoNFC + f.infoString = lookupInfoStringNFC + } + if Form(i) == NFC || Form(i) == NFKC { + f.composing = true + f.boundaryBefore = compBoundaryBefore + f.boundaryAfter = compBoundaryAfter + } else { + f.boundaryBefore = decompBoundary + f.boundaryAfter = decompBoundary + } + } +} + +func decompBoundary(f *formInfo, info runeInfo) bool { + if info.ccc == 0 && info.flags.isYesD() { // Implies isHangul(b) == true + return true + } + // We assume that the CCC of the first character in a decomposition + // is always non-zero if different from info.ccc and that we can return + // false at this point. This is verified by maketables. + return false +} + +func compBoundaryBefore(f *formInfo, info runeInfo) bool { + if info.ccc == 0 && info.flags.isYesC() { + return true + } + // We assume that the CCC of the first character in a decomposition + // is always non-zero if different from info.ccc and that we can return + // false at this point. This is verified by maketables. + return false +} + +func compBoundaryAfter(f *formInfo, info runeInfo) bool { + // This misses values where the last char in a decomposition is a + // boundary such as Hangul with JamoT. + // TODO(mpvl): verify this does not lead to segments that do + // not fit in the reorderBuffer. + return info.flags.isInert() +} + +// We pack quick check data in 4 bits: +// 0: NFD_QC Yes (0) or No (1). No also means there is a decomposition. +// 1..2: NFC_QC Yes(00), No (01), or Maybe (11) +// 3: Combines forward (0 == false, 1 == true) +// +// When all 4 bits are zero, the character is inert, meaning it is never +// influenced by normalization. +// +// We pack the bits for both NFC/D and NFKC/D in one byte. +type qcInfo uint8 + +func (i qcInfo) isYesC() bool { return i&0x2 == 0 } +func (i qcInfo) isNoC() bool { return i&0x6 == 0x2 } +func (i qcInfo) isMaybe() bool { return i&0x4 != 0 } +func (i qcInfo) isYesD() bool { return i&0x1 == 0 } +func (i qcInfo) isNoD() bool { return i&0x1 != 0 } +func (i qcInfo) isInert() bool { return i&0xf == 0 } + +func (i qcInfo) combinesForward() bool { return i&0x8 != 0 } +func (i qcInfo) combinesBackward() bool { return i&0x4 != 0 } // == isMaybe +func (i qcInfo) hasDecomposition() bool { return i&0x1 != 0 } // == isNoD + +// Wrappers for tables.go + +// The 16-bit value of the decompostion tries is an index into a byte +// array of UTF-8 decomposition sequences. The first byte is the number +// of bytes in the decomposition (excluding this length byte). The actual +// sequence starts at the offset+1. +func decomposeNFC(b []byte) []byte { + p := nfcDecompTrie.lookupUnsafe(b) + n := decomps[p] + p++ + return decomps[p : p+uint16(n)] +} + +func decomposeNFKC(b []byte) []byte { + p := nfkcDecompTrie.lookupUnsafe(b) + n := decomps[p] + p++ + return decomps[p : p+uint16(n)] +} + +func decomposeStringNFC(s string) []byte { + p := nfcDecompTrie.lookupStringUnsafe(s) + n := decomps[p] + p++ + return decomps[p : p+uint16(n)] +} + +func decomposeStringNFKC(s string) []byte { + p := nfkcDecompTrie.lookupStringUnsafe(s) + n := decomps[p] + p++ + return decomps[p : p+uint16(n)] +} + +// Recomposition +// We use 32-bit keys instead of 64-bit for the two codepoint keys. +// This clips off the bits of three entries, but we know this will not +// result in a collision. In the unlikely event that changes to +// UnicodeData.txt introduce collisions, the compiler will catch it. +// Note that the recomposition map for NFC and NFKC are identical. + +// combine returns the combined rune or 0 if it doesn't exist. +func combine(a, b uint32) uint32 { + key := uint32(uint16(a))<<16 + uint32(uint16(b)) + return recompMap[key] +} + +// The 16-bit character info has the following bit layout: +// 0..7 CCC value. +// 8..11 qcInfo for NFC/NFD +// 12..15 qcInfo for NFKC/NFKD +func lookupInfoNFC(b []byte) runeInfo { + v, sz := charInfoTrie.lookup(b) + return runeInfo{0, uint8(sz), uint8(v), qcInfo(v >> 8)} +} + +func lookupInfoStringNFC(s string) runeInfo { + v, sz := charInfoTrie.lookupString(s) + return runeInfo{0, uint8(sz), uint8(v), qcInfo(v >> 8)} +} + +func lookupInfoNFKC(b []byte) runeInfo { + v, sz := charInfoTrie.lookup(b) + return runeInfo{0, uint8(sz), uint8(v), qcInfo(v >> 12)} +} + +func lookupInfoStringNFKC(s string) runeInfo { + v, sz := charInfoTrie.lookupString(s) + return runeInfo{0, uint8(sz), uint8(v), qcInfo(v >> 12)} +} diff --git a/libgo/go/exp/norm/maketables.go b/libgo/go/exp/norm/maketables.go new file mode 100644 index 00000000000..e3e5700a64e --- /dev/null +++ b/libgo/go/exp/norm/maketables.go @@ -0,0 +1,855 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Normalization table generator. +// Data read from the web. + +package main + +import ( + "bufio" + "bytes" + "flag" + "fmt" + "http" + "io" + "log" + "os" + "regexp" + "strconv" + "strings" +) + +func main() { + flag.Parse() + loadUnicodeData() + loadCompositionExclusions() + completeCharFields(FCanonical) + completeCharFields(FCompatibility) + verifyComputed() + printChars() + makeTables() + testDerived() +} + +var url = flag.String("url", + "http://www.unicode.org/Public/6.0.0/ucd/", + "URL of Unicode database directory") +var tablelist = flag.String("tables", + "all", + "comma-separated list of which tables to generate; "+ + "can be 'decomp', 'recomp', 'info' and 'all'") +var test = flag.Bool("test", + false, + "test existing tables; can be used to compare web data with package data") +var verbose = flag.Bool("verbose", + false, + "write data to stdout as it is parsed") +var localFiles = flag.Bool("local", + false, + "data files have been copied to the current directory; for debugging only") + +var logger = log.New(os.Stderr, "", log.Lshortfile) + +// UnicodeData.txt has form: +// 0037;DIGIT SEVEN;Nd;0;EN;;7;7;7;N;;;;; +// 007A;LATIN SMALL LETTER Z;Ll;0;L;;;;;N;;;005A;;005A +// See http://unicode.org/reports/tr44/ for full explanation +// The fields: +const ( + FCodePoint = iota + FName + FGeneralCategory + FCanonicalCombiningClass + FBidiClass + FDecompMapping + FDecimalValue + FDigitValue + FNumericValue + FBidiMirrored + FUnicode1Name + FISOComment + FSimpleUppercaseMapping + FSimpleLowercaseMapping + FSimpleTitlecaseMapping + NumField + + MaxChar = 0x10FFFF // anything above this shouldn't exist +) + +// Quick Check properties of runes allow us to quickly +// determine whether a rune may occur in a normal form. +// For a given normal form, a rune may be guaranteed to occur +// verbatim (QC=Yes), may or may not combine with another +// rune (QC=Maybe), or may not occur (QC=No). +type QCResult int + +const ( + QCUnknown QCResult = iota + QCYes + QCNo + QCMaybe +) + +func (r QCResult) String() string { + switch r { + case QCYes: + return "Yes" + case QCNo: + return "No" + case QCMaybe: + return "Maybe" + } + return "***UNKNOWN***" +} + +const ( + FCanonical = iota // NFC or NFD + FCompatibility // NFKC or NFKD + FNumberOfFormTypes +) + +const ( + MComposed = iota // NFC or NFKC + MDecomposed // NFD or NFKD + MNumberOfModes +) + +// This contains only the properties we're interested in. +type Char struct { + name string + codePoint int // if zero, this index is not a valid code point. + ccc uint8 // canonical combining class + excludeInComp bool // from CompositionExclusions.txt + compatDecomp bool // it has a compatibility expansion + + forms [FNumberOfFormTypes]FormInfo // For FCanonical and FCompatibility + + state State +} + +var chars = make([]Char, MaxChar+1) + +func (c Char) String() string { + buf := new(bytes.Buffer) + + fmt.Fprintf(buf, "%U [%s]:\n", c.codePoint, c.name) + fmt.Fprintf(buf, " ccc: %v\n", c.ccc) + fmt.Fprintf(buf, " excludeInComp: %v\n", c.excludeInComp) + fmt.Fprintf(buf, " compatDecomp: %v\n", c.compatDecomp) + fmt.Fprintf(buf, " state: %v\n", c.state) + fmt.Fprintf(buf, " NFC:\n") + fmt.Fprint(buf, c.forms[FCanonical]) + fmt.Fprintf(buf, " NFKC:\n") + fmt.Fprint(buf, c.forms[FCompatibility]) + + return buf.String() +} + +// In UnicodeData.txt, some ranges are marked like this: +// 3400;<CJK Ideograph Extension A, First>;Lo;0;L;;;;;N;;;;; +// 4DB5;<CJK Ideograph Extension A, Last>;Lo;0;L;;;;;N;;;;; +// parseCharacter keeps a state variable indicating the weirdness. +type State int + +const ( + SNormal State = iota // known to be zero for the type + SFirst + SLast + SMissing +) + +var lastChar int = 0 + +func (c Char) isValid() bool { + return c.codePoint != 0 && c.state != SMissing +} + +type FormInfo struct { + quickCheck [MNumberOfModes]QCResult // index: MComposed or MDecomposed + verified [MNumberOfModes]bool // index: MComposed or MDecomposed + + combinesForward bool // May combine with rune on the right + combinesBackward bool // May combine with rune on the left + isOneWay bool // Never appears in result + inDecomp bool // Some decompositions result in this char. + decomp Decomposition + expandedDecomp Decomposition +} + +func (f FormInfo) String() string { + buf := bytes.NewBuffer(make([]byte, 0)) + + fmt.Fprintf(buf, " quickCheck[C]: %v\n", f.quickCheck[MComposed]) + fmt.Fprintf(buf, " quickCheck[D]: %v\n", f.quickCheck[MDecomposed]) + fmt.Fprintf(buf, " cmbForward: %v\n", f.combinesForward) + fmt.Fprintf(buf, " cmbBackward: %v\n", f.combinesBackward) + fmt.Fprintf(buf, " isOneWay: %v\n", f.isOneWay) + fmt.Fprintf(buf, " inDecomp: %v\n", f.inDecomp) + fmt.Fprintf(buf, " decomposition: %v\n", f.decomp) + fmt.Fprintf(buf, " expandedDecomp: %v\n", f.expandedDecomp) + + return buf.String() +} + +type Decomposition []int + +func (d Decomposition) String() string { + return fmt.Sprintf("%.4X", d) +} + +func openReader(file string) (input io.ReadCloser) { + if *localFiles { + f, err := os.Open(file) + if err != nil { + logger.Fatal(err) + } + input = f + } else { + path := *url + file + resp, err := http.Get(path) + if err != nil { + logger.Fatal(err) + } + if resp.StatusCode != 200 { + logger.Fatal("bad GET status for "+file, resp.Status) + } + input = resp.Body + } + return +} + +func parseDecomposition(s string, skipfirst bool) (a []int, e os.Error) { + decomp := strings.Split(s, " ") + if len(decomp) > 0 && skipfirst { + decomp = decomp[1:] + } + for _, d := range decomp { + point, err := strconv.Btoui64(d, 16) + if err != nil { + return a, err + } + a = append(a, int(point)) + } + return a, nil +} + +func parseCharacter(line string) { + field := strings.Split(line, ";") + if len(field) != NumField { + logger.Fatalf("%5s: %d fields (expected %d)\n", line, len(field), NumField) + } + x, err := strconv.Btoui64(field[FCodePoint], 16) + point := int(x) + if err != nil { + logger.Fatalf("%.5s...: %s", line, err) + } + if point == 0 { + return // not interesting and we use 0 as unset + } + if point > MaxChar { + logger.Fatalf("%5s: Rune %X > MaxChar (%X)", line, point, MaxChar) + return + } + state := SNormal + switch { + case strings.Index(field[FName], ", First>") > 0: + state = SFirst + case strings.Index(field[FName], ", Last>") > 0: + state = SLast + } + firstChar := lastChar + 1 + lastChar = int(point) + if state != SLast { + firstChar = lastChar + } + x, err = strconv.Atoui64(field[FCanonicalCombiningClass]) + if err != nil { + logger.Fatalf("%U: bad ccc field: %s", int(x), err) + } + ccc := uint8(x) + decmap := field[FDecompMapping] + exp, e := parseDecomposition(decmap, false) + isCompat := false + if e != nil { + if len(decmap) > 0 { + exp, e = parseDecomposition(decmap, true) + if e != nil { + logger.Fatalf(`%U: bad decomp |%v|: "%s"`, int(x), decmap, e) + } + isCompat = true + } + } + for i := firstChar; i <= lastChar; i++ { + char := &chars[i] + char.name = field[FName] + char.codePoint = i + char.forms[FCompatibility].decomp = exp + if !isCompat { + char.forms[FCanonical].decomp = exp + } else { + char.compatDecomp = true + } + if len(decmap) > 0 { + char.forms[FCompatibility].decomp = exp + } + char.ccc = ccc + char.state = SMissing + if i == lastChar { + char.state = state + } + } + return +} + +func loadUnicodeData() { + f := openReader("UnicodeData.txt") + defer f.Close() + input := bufio.NewReader(f) + for { + line, err := input.ReadString('\n') + if err != nil { + if err == os.EOF { + break + } + logger.Fatal(err) + } + parseCharacter(line[0 : len(line)-1]) + } +} + +var singlePointRe = regexp.MustCompile(`^([0-9A-F]+) *$`) + +// CompositionExclusions.txt has form: +// 0958 # ... +// See http://unicode.org/reports/tr44/ for full explanation +func parseExclusion(line string) int { + comment := strings.Index(line, "#") + if comment >= 0 { + line = line[0:comment] + } + if len(line) == 0 { + return 0 + } + matches := singlePointRe.FindStringSubmatch(line) + if len(matches) != 2 { + logger.Fatalf("%s: %d matches (expected 1)\n", line, len(matches)) + } + point, err := strconv.Btoui64(matches[1], 16) + if err != nil { + logger.Fatalf("%.5s...: %s", line, err) + } + return int(point) +} + +func loadCompositionExclusions() { + f := openReader("CompositionExclusions.txt") + defer f.Close() + input := bufio.NewReader(f) + for { + line, err := input.ReadString('\n') + if err != nil { + if err == os.EOF { + break + } + logger.Fatal(err) + } + point := parseExclusion(line[0 : len(line)-1]) + if point == 0 { + continue + } + c := &chars[point] + if c.excludeInComp { + logger.Fatalf("%U: Duplicate entry in exclusions.", c.codePoint) + } + c.excludeInComp = true + } +} + +// hasCompatDecomp returns true if any of the recursive +// decompositions contains a compatibility expansion. +// In this case, the character may not occur in NFK*. +func hasCompatDecomp(rune int) bool { + c := &chars[rune] + if c.compatDecomp { + return true + } + for _, d := range c.forms[FCompatibility].decomp { + if hasCompatDecomp(d) { + return true + } + } + return false +} + +// Hangul related constants. +const ( + HangulBase = 0xAC00 + HangulEnd = 0xD7A4 // hangulBase + Jamo combinations (19 * 21 * 28) + + JamoLBase = 0x1100 + JamoLEnd = 0x1113 + JamoVBase = 0x1161 + JamoVEnd = 0x1176 + JamoTBase = 0x11A8 + JamoTEnd = 0x11C3 +) + +func isHangul(rune int) bool { + return HangulBase <= rune && rune < HangulEnd +} + +func ccc(rune int) uint8 { + return chars[rune].ccc +} + +// Insert a rune in a buffer, ordered by Canonical Combining Class. +func insertOrdered(b Decomposition, rune int) Decomposition { + n := len(b) + b = append(b, 0) + cc := ccc(rune) + if cc > 0 { + // Use bubble sort. + for ; n > 0; n-- { + if ccc(b[n-1]) <= cc { + break + } + b[n] = b[n-1] + } + } + b[n] = rune + return b +} + +// Recursively decompose. +func decomposeRecursive(form int, rune int, d Decomposition) Decomposition { + if isHangul(rune) { + return d + } + dcomp := chars[rune].forms[form].decomp + if len(dcomp) == 0 { + return insertOrdered(d, rune) + } + for _, c := range dcomp { + d = decomposeRecursive(form, c, d) + } + return d +} + +func completeCharFields(form int) { + // Phase 0: pre-expand decomposition. + for i := range chars { + f := &chars[i].forms[form] + if len(f.decomp) == 0 { + continue + } + exp := make(Decomposition, 0) + for _, c := range f.decomp { + exp = decomposeRecursive(form, c, exp) + } + f.expandedDecomp = exp + } + + // Phase 1: composition exclusion, mark decomposition. + for i := range chars { + c := &chars[i] + f := &c.forms[form] + + // Marks script-specific exclusions and version restricted. + f.isOneWay = c.excludeInComp + + // Singletons + f.isOneWay = f.isOneWay || len(f.decomp) == 1 + + // Non-starter decompositions + if len(f.decomp) > 1 { + chk := c.ccc != 0 || chars[f.decomp[0]].ccc != 0 + f.isOneWay = f.isOneWay || chk + } + + // Runes that decompose into more than two runes. + f.isOneWay = f.isOneWay || len(f.decomp) > 2 + + if form == FCompatibility { + f.isOneWay = f.isOneWay || hasCompatDecomp(c.codePoint) + } + + for _, rune := range f.decomp { + chars[rune].forms[form].inDecomp = true + } + } + + // Phase 2: forward and backward combining. + for i := range chars { + c := &chars[i] + f := &c.forms[form] + + if !f.isOneWay && len(f.decomp) == 2 { + f0 := &chars[f.decomp[0]].forms[form] + f1 := &chars[f.decomp[1]].forms[form] + if !f0.isOneWay { + f0.combinesForward = true + } + if !f1.isOneWay { + f1.combinesBackward = true + } + } + } + + // Phase 3: quick check values. + for i := range chars { + c := &chars[i] + f := &c.forms[form] + + switch { + case len(f.decomp) > 0: + f.quickCheck[MDecomposed] = QCNo + case isHangul(i): + f.quickCheck[MDecomposed] = QCNo + default: + f.quickCheck[MDecomposed] = QCYes + } + switch { + case f.isOneWay: + f.quickCheck[MComposed] = QCNo + case (i & 0xffff00) == JamoLBase: + f.quickCheck[MComposed] = QCYes + if JamoVBase <= i && i < JamoVEnd { + f.quickCheck[MComposed] = QCMaybe + f.combinesBackward = true + } + if JamoTBase <= i && i < JamoTEnd { + f.quickCheck[MComposed] = QCMaybe + f.combinesBackward = true + } + case !f.combinesBackward: + f.quickCheck[MComposed] = QCYes + default: + f.quickCheck[MComposed] = QCMaybe + } + } +} + +func printBytes(b []byte, name string) { + fmt.Printf("// %s: %d bytes\n", name, len(b)) + fmt.Printf("var %s = [...]byte {", name) + for i, c := range b { + switch { + case i%64 == 0: + fmt.Printf("\n// Bytes %x - %x\n", i, i+63) + case i%8 == 0: + fmt.Printf("\n") + } + fmt.Printf("0x%.2X, ", c) + } + fmt.Print("\n}\n\n") +} + +// See forminfo.go for format. +func makeEntry(f *FormInfo) uint16 { + e := uint16(0) + if f.combinesForward { + e |= 0x8 + } + if f.quickCheck[MDecomposed] == QCNo { + e |= 0x1 + } + switch f.quickCheck[MComposed] { + case QCYes: + case QCNo: + e |= 0x2 + case QCMaybe: + e |= 0x6 + default: + log.Fatalf("Illegal quickcheck value %d.", f.quickCheck[MComposed]) + } + return e +} + +// Bits +// 0..8: CCC +// 9..12: NF(C|D) qc bits. +// 13..16: NFK(C|D) qc bits. +func makeCharInfo(c Char) uint16 { + e := makeEntry(&c.forms[FCompatibility]) + e = e<<4 | makeEntry(&c.forms[FCanonical]) + e = e<<8 | uint16(c.ccc) + return e +} + +func printCharInfoTables() int { + // Quick Check + CCC trie. + t := newNode() + for i, char := range chars { + v := makeCharInfo(char) + if v != 0 { + t.insert(i, v) + } + } + return t.printTables("charInfo") +} + +func printDecompositionTables() int { + decompositions := bytes.NewBuffer(make([]byte, 0, 10000)) + size := 0 + + // Map decompositions + positionMap := make(map[string]uint16) + + // Store the uniqued decompositions in a byte buffer, + // preceded by their byte length. + for _, c := range chars { + for f := 0; f < 2; f++ { + d := c.forms[f].expandedDecomp + s := string([]int(d)) + if _, ok := positionMap[s]; !ok { + p := decompositions.Len() + decompositions.WriteByte(uint8(len(s))) + decompositions.WriteString(s) + positionMap[s] = uint16(p) + } + } + } + b := decompositions.Bytes() + printBytes(b, "decomps") + size += len(b) + + nfcT := newNode() + nfkcT := newNode() + for i, c := range chars { + d := c.forms[FCanonical].expandedDecomp + if len(d) != 0 { + nfcT.insert(i, positionMap[string([]int(d))]) + if ccc(c.codePoint) != ccc(d[0]) { + // We assume the lead ccc of a decomposition is !=0 in this case. + if ccc(d[0]) == 0 { + logger.Fatal("Expected differing CCC to be non-zero.") + } + } + } + d = c.forms[FCompatibility].expandedDecomp + if len(d) != 0 { + nfkcT.insert(i, positionMap[string([]int(d))]) + if ccc(c.codePoint) != ccc(d[0]) { + // We assume the lead ccc of a decomposition is !=0 in this case. + if ccc(d[0]) == 0 { + logger.Fatal("Expected differing CCC to be non-zero.") + } + } + } + } + size += nfcT.printTables("nfcDecomp") + size += nfkcT.printTables("nfkcDecomp") + return size +} + +func contains(sa []string, s string) bool { + for _, a := range sa { + if a == s { + return true + } + } + return false +} + +// Extract the version number from the URL. +func version() string { + // From http://www.unicode.org/standard/versions/#Version_Numbering: + // for the later Unicode versions, data files are located in + // versioned directories. + fields := strings.Split(*url, "/") + for _, f := range fields { + if match, _ := regexp.MatchString(`[0-9]\.[0-9]\.[0-9]`, f); match { + return f + } + } + logger.Fatal("unknown version") + return "Unknown" +} + +const fileHeader = `// Generated by running +// maketables --tables=%s --url=%s +// DO NOT EDIT + +package norm + +` + +func makeTables() { + size := 0 + if *tablelist == "" { + return + } + list := strings.Split(*tablelist, ",") + if *tablelist == "all" { + list = []string{"decomp", "recomp", "info"} + } + fmt.Printf(fileHeader, *tablelist, *url) + + fmt.Println("// Version is the Unicode edition from which the tables are derived.") + fmt.Printf("const Version = %q\n\n", version()) + + if contains(list, "decomp") { + size += printDecompositionTables() + } + + if contains(list, "recomp") { + // Note that we use 32 bit keys, instead of 64 bit. + // This clips the bits of three entries, but we know + // this won't cause a collision. The compiler will catch + // any changes made to UnicodeData.txt that introduces + // a collision. + // Note that the recomposition map for NFC and NFKC + // are identical. + + // Recomposition map + nrentries := 0 + for _, c := range chars { + f := c.forms[FCanonical] + if !f.isOneWay && len(f.decomp) > 0 { + nrentries++ + } + } + sz := nrentries * 8 + size += sz + fmt.Printf("// recompMap: %d bytes (entries only)\n", sz) + fmt.Println("var recompMap = map[uint32]uint32{") + for i, c := range chars { + f := c.forms[FCanonical] + d := f.decomp + if !f.isOneWay && len(d) > 0 { + key := uint32(uint16(d[0]))<<16 + uint32(uint16(d[1])) + fmt.Printf("0x%.8X: 0x%.4X,\n", key, i) + } + } + fmt.Printf("}\n\n") + } + + if contains(list, "info") { + size += printCharInfoTables() + } + fmt.Printf("// Total size of tables: %dKB (%d bytes)\n", (size+512)/1024, size) +} + +func printChars() { + if *verbose { + for _, c := range chars { + if !c.isValid() || c.state == SMissing { + continue + } + fmt.Println(c) + } + } +} + +// verifyComputed does various consistency tests. +func verifyComputed() { + for i, c := range chars { + for _, f := range c.forms { + isNo := (f.quickCheck[MDecomposed] == QCNo) + if (len(f.decomp) > 0) != isNo && !isHangul(i) { + log.Fatalf("%U: NF*D must be no if rune decomposes", i) + } + + isMaybe := f.quickCheck[MComposed] == QCMaybe + if f.combinesBackward != isMaybe { + log.Fatalf("%U: NF*C must be maybe if combinesBackward", i) + } + } + } +} + +var qcRe = regexp.MustCompile(`^([0-9A-F\.]+) *; (NF.*_QC); ([YNM]) #.*$`) + +// Use values in DerivedNormalizationProps.txt to compare against the +// values we computed. +// DerivedNormalizationProps.txt has form: +// 00C0..00C5 ; NFD_QC; N # ... +// 0374 ; NFD_QC; N # ... +// See http://unicode.org/reports/tr44/ for full explanation +func testDerived() { + if !*test { + return + } + f := openReader("DerivedNormalizationProps.txt") + defer f.Close() + input := bufio.NewReader(f) + for { + line, err := input.ReadString('\n') + if err != nil { + if err == os.EOF { + break + } + logger.Fatal(err) + } + qc := qcRe.FindStringSubmatch(line) + if qc == nil { + continue + } + rng := strings.Split(qc[1], "..") + i, err := strconv.Btoui64(rng[0], 16) + if err != nil { + log.Fatal(err) + } + j := i + if len(rng) > 1 { + j, err = strconv.Btoui64(rng[1], 16) + if err != nil { + log.Fatal(err) + } + } + var ftype, mode int + qt := strings.TrimSpace(qc[2]) + switch qt { + case "NFC_QC": + ftype, mode = FCanonical, MComposed + case "NFD_QC": + ftype, mode = FCanonical, MDecomposed + case "NFKC_QC": + ftype, mode = FCompatibility, MComposed + case "NFKD_QC": + ftype, mode = FCompatibility, MDecomposed + default: + log.Fatalf(`Unexpected quick check type "%s"`, qt) + } + var qr QCResult + switch qc[3] { + case "Y": + qr = QCYes + case "N": + qr = QCNo + case "M": + qr = QCMaybe + default: + log.Fatalf(`Unexpected quick check value "%s"`, qc[3]) + } + var lastFailed bool + // Verify current + for ; i <= j; i++ { + c := &chars[int(i)] + c.forms[ftype].verified[mode] = true + curqr := c.forms[ftype].quickCheck[mode] + if curqr != qr { + if !lastFailed { + logger.Printf("%s: %.4X..%.4X -- %s\n", + qt, int(i), int(j), line[0:50]) + } + logger.Printf("%U: FAILED %s (was %v need %v)\n", + int(i), qt, curqr, qr) + lastFailed = true + } + } + } + // Any unspecified value must be QCYes. Verify this. + for i, c := range chars { + for j, fd := range c.forms { + for k, qr := range fd.quickCheck { + if !fd.verified[k] && qr != QCYes { + m := "%U: FAIL F:%d M:%d (was %v need Yes) %s\n" + logger.Printf(m, i, j, k, qr, c.name) + } + } + } + } +} diff --git a/libgo/go/exp/norm/maketesttables.go b/libgo/go/exp/norm/maketesttables.go new file mode 100644 index 00000000000..c5f6a64368d --- /dev/null +++ b/libgo/go/exp/norm/maketesttables.go @@ -0,0 +1,42 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Generate test data for trie code. + +package main + +import ( + "fmt" +) + +func main() { + printTestTables() +} + +// We take the smallest, largest and an arbitrary value for each +// of the UTF-8 sequence lengths. +var testRunes = []int{ + 0x01, 0x0C, 0x7F, // 1-byte sequences + 0x80, 0x100, 0x7FF, // 2-byte sequences + 0x800, 0x999, 0xFFFF, // 3-byte sequences + 0x10000, 0x10101, 0x10FFFF, // 4-byte sequences +} + +const fileHeader = `// Generated by running +// maketesttables +// DO NOT EDIT + +package norm + +` + +func printTestTables() { + fmt.Print(fileHeader) + fmt.Printf("var testRunes = %#v\n\n", testRunes) + t := newNode() + for i, r := range testRunes { + t.insert(r, uint16(i)) + } + t.printTables("testdata") +} diff --git a/libgo/go/exp/norm/norm_test.go b/libgo/go/exp/norm/norm_test.go new file mode 100644 index 00000000000..12dacfcf300 --- /dev/null +++ b/libgo/go/exp/norm/norm_test.go @@ -0,0 +1,14 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package norm_test + +import ( + "testing" +) + +func TestPlaceHolder(t *testing.T) { + // Does nothing, just allows the Makefile to be canonical + // while waiting for the package itself to be written. +} diff --git a/libgo/go/exp/norm/normalize.go b/libgo/go/exp/norm/normalize.go new file mode 100644 index 00000000000..e9d18dd9ea9 --- /dev/null +++ b/libgo/go/exp/norm/normalize.go @@ -0,0 +1,99 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package norm contains types and functions for normalizing Unicode strings. +package norm + +// A Form denotes a canonical representation of Unicode code points. +// The Unicode-defined normalization and equivalence forms are: +// +// NFC Unicode Normalization Form C +// NFD Unicode Normalization Form D +// NFKC Unicode Normalization Form KC +// NFKD Unicode Normalization Form KD +// +// For a Form f, this documentation uses the notation f(x) to mean +// the bytes or string x converted to the given form. +// A position n in x is called a boundary if conversion to the form can +// proceed independently on both sides: +// f(x) == append(f(x[0:n]), f(x[n:])...) +// +// References: http://unicode.org/reports/tr15/ and +// http://unicode.org/notes/tn5/. +type Form int + +const ( + NFC Form = iota + NFD + NFKC + NFKD +) + +// Bytes returns f(b). May return b if f(b) = b. +func (f Form) Bytes(b []byte) []byte { + panic("not implemented") +} + +// String returns f(s). +func (f Form) String(s string) string { + panic("not implemented") +} + +// IsNormal returns true if b == f(b). +func (f Form) IsNormal(b []byte) bool { + panic("not implemented") +} + +// IsNormalString returns true if s == f(s). +func (f Form) IsNormalString(s string) bool { + panic("not implemented") +} + +// Append returns f(append(out, b...)). +// The buffer out must be empty or equal to f(out). +func (f Form) Append(out, b []byte) []byte { + panic("not implemented") +} + +// AppendString returns f(append(out, []byte(s))). +// The buffer out must be empty or equal to f(out). +func (f Form) AppendString(out []byte, s string) []byte { + panic("not implemented") +} + +// QuickSpan returns a boundary n such that b[0:n] == f(b[0:n]). +// It is not guaranteed to return the largest such n. +func (f Form) QuickSpan(b []byte) int { + panic("not implemented") +} + +// QuickSpanString returns a boundary n such that b[0:n] == f(s[0:n]). +// It is not guaranteed to return the largest such n. +func (f Form) QuickSpanString(s string) int { + panic("not implemented") +} + +// FirstBoundary returns the position i of the first boundary in b. +// It returns len(b), false if b contains no boundaries. +func (f Form) FirstBoundary(b []byte) (i int, ok bool) { + panic("not implemented") +} + +// FirstBoundaryInString return the position i of the first boundary in s. +// It returns len(s), false if s contains no boundaries. +func (f Form) FirstBoundaryInString(s string) (i int, ok bool) { + panic("not implemented") +} + +// LastBoundaryIn returns the position i of the last boundary in b. +// It returns 0, false if b contains no boundary. +func (f Form) LastBoundary(b []byte) (i int, ok bool) { + panic("not implemented") +} + +// LastBoundaryInString returns the position i of the last boundary in s. +// It returns 0, false if s contains no boundary. +func (f Form) LastBoundaryInString(s string) (i int, ok bool) { + panic("not implemented") +} diff --git a/libgo/go/exp/norm/tables.go b/libgo/go/exp/norm/tables.go new file mode 100644 index 00000000000..76995c2fa18 --- /dev/null +++ b/libgo/go/exp/norm/tables.go @@ -0,0 +1,6580 @@ +// Generated by running +// maketables --tables=all --url=http://www.unicode.org/Public/6.0.0/ucd/ +// DO NOT EDIT + +package norm + +// Version is the Unicode edition from which the tables are derived. +const Version = "6.0.0" + +// decomps: 17618 bytes +var decomps = [...]byte{ + // Bytes 0 - 3f + 0x00, 0x01, 0x20, 0x03, 0x20, 0xCC, 0x88, 0x01, + 0x61, 0x03, 0x20, 0xCC, 0x84, 0x01, 0x32, 0x01, + 0x33, 0x03, 0x20, 0xCC, 0x81, 0x02, 0xCE, 0xBC, + 0x03, 0x20, 0xCC, 0xA7, 0x01, 0x31, 0x01, 0x6F, + 0x05, 0x31, 0xE2, 0x81, 0x84, 0x34, 0x05, 0x31, + 0xE2, 0x81, 0x84, 0x32, 0x05, 0x33, 0xE2, 0x81, + 0x84, 0x34, 0x03, 0x41, 0xCC, 0x80, 0x03, 0x41, + 0xCC, 0x81, 0x03, 0x41, 0xCC, 0x82, 0x03, 0x41, + // Bytes 40 - 7f + 0xCC, 0x83, 0x03, 0x41, 0xCC, 0x88, 0x03, 0x41, + 0xCC, 0x8A, 0x03, 0x43, 0xCC, 0xA7, 0x03, 0x45, + 0xCC, 0x80, 0x03, 0x45, 0xCC, 0x81, 0x03, 0x45, + 0xCC, 0x82, 0x03, 0x45, 0xCC, 0x88, 0x03, 0x49, + 0xCC, 0x80, 0x03, 0x49, 0xCC, 0x81, 0x03, 0x49, + 0xCC, 0x82, 0x03, 0x49, 0xCC, 0x88, 0x03, 0x4E, + 0xCC, 0x83, 0x03, 0x4F, 0xCC, 0x80, 0x03, 0x4F, + 0xCC, 0x81, 0x03, 0x4F, 0xCC, 0x82, 0x03, 0x4F, + // Bytes 80 - bf + 0xCC, 0x83, 0x03, 0x4F, 0xCC, 0x88, 0x03, 0x55, + 0xCC, 0x80, 0x03, 0x55, 0xCC, 0x81, 0x03, 0x55, + 0xCC, 0x82, 0x03, 0x55, 0xCC, 0x88, 0x03, 0x59, + 0xCC, 0x81, 0x03, 0x61, 0xCC, 0x80, 0x03, 0x61, + 0xCC, 0x81, 0x03, 0x61, 0xCC, 0x82, 0x03, 0x61, + 0xCC, 0x83, 0x03, 0x61, 0xCC, 0x88, 0x03, 0x61, + 0xCC, 0x8A, 0x03, 0x63, 0xCC, 0xA7, 0x03, 0x65, + 0xCC, 0x80, 0x03, 0x65, 0xCC, 0x81, 0x03, 0x65, + // Bytes c0 - ff + 0xCC, 0x82, 0x03, 0x65, 0xCC, 0x88, 0x03, 0x69, + 0xCC, 0x80, 0x03, 0x69, 0xCC, 0x81, 0x03, 0x69, + 0xCC, 0x82, 0x03, 0x69, 0xCC, 0x88, 0x03, 0x6E, + 0xCC, 0x83, 0x03, 0x6F, 0xCC, 0x80, 0x03, 0x6F, + 0xCC, 0x81, 0x03, 0x6F, 0xCC, 0x82, 0x03, 0x6F, + 0xCC, 0x83, 0x03, 0x6F, 0xCC, 0x88, 0x03, 0x75, + 0xCC, 0x80, 0x03, 0x75, 0xCC, 0x81, 0x03, 0x75, + 0xCC, 0x82, 0x03, 0x75, 0xCC, 0x88, 0x03, 0x79, + // Bytes 100 - 13f + 0xCC, 0x81, 0x03, 0x79, 0xCC, 0x88, 0x03, 0x41, + 0xCC, 0x84, 0x03, 0x61, 0xCC, 0x84, 0x03, 0x41, + 0xCC, 0x86, 0x03, 0x61, 0xCC, 0x86, 0x03, 0x41, + 0xCC, 0xA8, 0x03, 0x61, 0xCC, 0xA8, 0x03, 0x43, + 0xCC, 0x81, 0x03, 0x63, 0xCC, 0x81, 0x03, 0x43, + 0xCC, 0x82, 0x03, 0x63, 0xCC, 0x82, 0x03, 0x43, + 0xCC, 0x87, 0x03, 0x63, 0xCC, 0x87, 0x03, 0x43, + 0xCC, 0x8C, 0x03, 0x63, 0xCC, 0x8C, 0x03, 0x44, + // Bytes 140 - 17f + 0xCC, 0x8C, 0x03, 0x64, 0xCC, 0x8C, 0x03, 0x45, + 0xCC, 0x84, 0x03, 0x65, 0xCC, 0x84, 0x03, 0x45, + 0xCC, 0x86, 0x03, 0x65, 0xCC, 0x86, 0x03, 0x45, + 0xCC, 0x87, 0x03, 0x65, 0xCC, 0x87, 0x03, 0x45, + 0xCC, 0xA8, 0x03, 0x65, 0xCC, 0xA8, 0x03, 0x45, + 0xCC, 0x8C, 0x03, 0x65, 0xCC, 0x8C, 0x03, 0x47, + 0xCC, 0x82, 0x03, 0x67, 0xCC, 0x82, 0x03, 0x47, + 0xCC, 0x86, 0x03, 0x67, 0xCC, 0x86, 0x03, 0x47, + // Bytes 180 - 1bf + 0xCC, 0x87, 0x03, 0x67, 0xCC, 0x87, 0x03, 0x47, + 0xCC, 0xA7, 0x03, 0x67, 0xCC, 0xA7, 0x03, 0x48, + 0xCC, 0x82, 0x03, 0x68, 0xCC, 0x82, 0x03, 0x49, + 0xCC, 0x83, 0x03, 0x69, 0xCC, 0x83, 0x03, 0x49, + 0xCC, 0x84, 0x03, 0x69, 0xCC, 0x84, 0x03, 0x49, + 0xCC, 0x86, 0x03, 0x69, 0xCC, 0x86, 0x03, 0x49, + 0xCC, 0xA8, 0x03, 0x69, 0xCC, 0xA8, 0x03, 0x49, + 0xCC, 0x87, 0x02, 0x49, 0x4A, 0x02, 0x69, 0x6A, + // Bytes 1c0 - 1ff + 0x03, 0x4A, 0xCC, 0x82, 0x03, 0x6A, 0xCC, 0x82, + 0x03, 0x4B, 0xCC, 0xA7, 0x03, 0x6B, 0xCC, 0xA7, + 0x03, 0x4C, 0xCC, 0x81, 0x03, 0x6C, 0xCC, 0x81, + 0x03, 0x4C, 0xCC, 0xA7, 0x03, 0x6C, 0xCC, 0xA7, + 0x03, 0x4C, 0xCC, 0x8C, 0x03, 0x6C, 0xCC, 0x8C, + 0x03, 0x4C, 0xC2, 0xB7, 0x03, 0x6C, 0xC2, 0xB7, + 0x03, 0x4E, 0xCC, 0x81, 0x03, 0x6E, 0xCC, 0x81, + 0x03, 0x4E, 0xCC, 0xA7, 0x03, 0x6E, 0xCC, 0xA7, + // Bytes 200 - 23f + 0x03, 0x4E, 0xCC, 0x8C, 0x03, 0x6E, 0xCC, 0x8C, + 0x03, 0xCA, 0xBC, 0x6E, 0x03, 0x4F, 0xCC, 0x84, + 0x03, 0x6F, 0xCC, 0x84, 0x03, 0x4F, 0xCC, 0x86, + 0x03, 0x6F, 0xCC, 0x86, 0x03, 0x4F, 0xCC, 0x8B, + 0x03, 0x6F, 0xCC, 0x8B, 0x03, 0x52, 0xCC, 0x81, + 0x03, 0x72, 0xCC, 0x81, 0x03, 0x52, 0xCC, 0xA7, + 0x03, 0x72, 0xCC, 0xA7, 0x03, 0x52, 0xCC, 0x8C, + 0x03, 0x72, 0xCC, 0x8C, 0x03, 0x53, 0xCC, 0x81, + // Bytes 240 - 27f + 0x03, 0x73, 0xCC, 0x81, 0x03, 0x53, 0xCC, 0x82, + 0x03, 0x73, 0xCC, 0x82, 0x03, 0x53, 0xCC, 0xA7, + 0x03, 0x73, 0xCC, 0xA7, 0x03, 0x53, 0xCC, 0x8C, + 0x03, 0x73, 0xCC, 0x8C, 0x03, 0x54, 0xCC, 0xA7, + 0x03, 0x74, 0xCC, 0xA7, 0x03, 0x54, 0xCC, 0x8C, + 0x03, 0x74, 0xCC, 0x8C, 0x03, 0x55, 0xCC, 0x83, + 0x03, 0x75, 0xCC, 0x83, 0x03, 0x55, 0xCC, 0x84, + 0x03, 0x75, 0xCC, 0x84, 0x03, 0x55, 0xCC, 0x86, + // Bytes 280 - 2bf + 0x03, 0x75, 0xCC, 0x86, 0x03, 0x55, 0xCC, 0x8A, + 0x03, 0x75, 0xCC, 0x8A, 0x03, 0x55, 0xCC, 0x8B, + 0x03, 0x75, 0xCC, 0x8B, 0x03, 0x55, 0xCC, 0xA8, + 0x03, 0x75, 0xCC, 0xA8, 0x03, 0x57, 0xCC, 0x82, + 0x03, 0x77, 0xCC, 0x82, 0x03, 0x59, 0xCC, 0x82, + 0x03, 0x79, 0xCC, 0x82, 0x03, 0x59, 0xCC, 0x88, + 0x03, 0x5A, 0xCC, 0x81, 0x03, 0x7A, 0xCC, 0x81, + 0x03, 0x5A, 0xCC, 0x87, 0x03, 0x7A, 0xCC, 0x87, + // Bytes 2c0 - 2ff + 0x03, 0x5A, 0xCC, 0x8C, 0x03, 0x7A, 0xCC, 0x8C, + 0x01, 0x73, 0x03, 0x4F, 0xCC, 0x9B, 0x03, 0x6F, + 0xCC, 0x9B, 0x03, 0x55, 0xCC, 0x9B, 0x03, 0x75, + 0xCC, 0x9B, 0x04, 0x44, 0x5A, 0xCC, 0x8C, 0x04, + 0x44, 0x7A, 0xCC, 0x8C, 0x04, 0x64, 0x7A, 0xCC, + 0x8C, 0x02, 0x4C, 0x4A, 0x02, 0x4C, 0x6A, 0x02, + 0x6C, 0x6A, 0x02, 0x4E, 0x4A, 0x02, 0x4E, 0x6A, + 0x02, 0x6E, 0x6A, 0x03, 0x41, 0xCC, 0x8C, 0x03, + // Bytes 300 - 33f + 0x61, 0xCC, 0x8C, 0x03, 0x49, 0xCC, 0x8C, 0x03, + 0x69, 0xCC, 0x8C, 0x03, 0x4F, 0xCC, 0x8C, 0x03, + 0x6F, 0xCC, 0x8C, 0x03, 0x55, 0xCC, 0x8C, 0x03, + 0x75, 0xCC, 0x8C, 0x05, 0x55, 0xCC, 0x88, 0xCC, + 0x84, 0x05, 0x75, 0xCC, 0x88, 0xCC, 0x84, 0x05, + 0x55, 0xCC, 0x88, 0xCC, 0x81, 0x05, 0x75, 0xCC, + 0x88, 0xCC, 0x81, 0x05, 0x55, 0xCC, 0x88, 0xCC, + 0x8C, 0x05, 0x75, 0xCC, 0x88, 0xCC, 0x8C, 0x05, + // Bytes 340 - 37f + 0x55, 0xCC, 0x88, 0xCC, 0x80, 0x05, 0x75, 0xCC, + 0x88, 0xCC, 0x80, 0x05, 0x41, 0xCC, 0x88, 0xCC, + 0x84, 0x05, 0x61, 0xCC, 0x88, 0xCC, 0x84, 0x05, + 0x41, 0xCC, 0x87, 0xCC, 0x84, 0x05, 0x61, 0xCC, + 0x87, 0xCC, 0x84, 0x04, 0xC3, 0x86, 0xCC, 0x84, + 0x04, 0xC3, 0xA6, 0xCC, 0x84, 0x03, 0x47, 0xCC, + 0x8C, 0x03, 0x67, 0xCC, 0x8C, 0x03, 0x4B, 0xCC, + 0x8C, 0x03, 0x6B, 0xCC, 0x8C, 0x03, 0x4F, 0xCC, + // Bytes 380 - 3bf + 0xA8, 0x03, 0x6F, 0xCC, 0xA8, 0x05, 0x4F, 0xCC, + 0xA8, 0xCC, 0x84, 0x05, 0x6F, 0xCC, 0xA8, 0xCC, + 0x84, 0x04, 0xC6, 0xB7, 0xCC, 0x8C, 0x04, 0xCA, + 0x92, 0xCC, 0x8C, 0x03, 0x6A, 0xCC, 0x8C, 0x02, + 0x44, 0x5A, 0x02, 0x44, 0x7A, 0x02, 0x64, 0x7A, + 0x03, 0x47, 0xCC, 0x81, 0x03, 0x67, 0xCC, 0x81, + 0x03, 0x4E, 0xCC, 0x80, 0x03, 0x6E, 0xCC, 0x80, + 0x05, 0x41, 0xCC, 0x8A, 0xCC, 0x81, 0x05, 0x61, + // Bytes 3c0 - 3ff + 0xCC, 0x8A, 0xCC, 0x81, 0x04, 0xC3, 0x86, 0xCC, + 0x81, 0x04, 0xC3, 0xA6, 0xCC, 0x81, 0x04, 0xC3, + 0x98, 0xCC, 0x81, 0x04, 0xC3, 0xB8, 0xCC, 0x81, + 0x03, 0x41, 0xCC, 0x8F, 0x03, 0x61, 0xCC, 0x8F, + 0x03, 0x41, 0xCC, 0x91, 0x03, 0x61, 0xCC, 0x91, + 0x03, 0x45, 0xCC, 0x8F, 0x03, 0x65, 0xCC, 0x8F, + 0x03, 0x45, 0xCC, 0x91, 0x03, 0x65, 0xCC, 0x91, + 0x03, 0x49, 0xCC, 0x8F, 0x03, 0x69, 0xCC, 0x8F, + // Bytes 400 - 43f + 0x03, 0x49, 0xCC, 0x91, 0x03, 0x69, 0xCC, 0x91, + 0x03, 0x4F, 0xCC, 0x8F, 0x03, 0x6F, 0xCC, 0x8F, + 0x03, 0x4F, 0xCC, 0x91, 0x03, 0x6F, 0xCC, 0x91, + 0x03, 0x52, 0xCC, 0x8F, 0x03, 0x72, 0xCC, 0x8F, + 0x03, 0x52, 0xCC, 0x91, 0x03, 0x72, 0xCC, 0x91, + 0x03, 0x55, 0xCC, 0x8F, 0x03, 0x75, 0xCC, 0x8F, + 0x03, 0x55, 0xCC, 0x91, 0x03, 0x75, 0xCC, 0x91, + 0x03, 0x53, 0xCC, 0xA6, 0x03, 0x73, 0xCC, 0xA6, + // Bytes 440 - 47f + 0x03, 0x54, 0xCC, 0xA6, 0x03, 0x74, 0xCC, 0xA6, + 0x03, 0x48, 0xCC, 0x8C, 0x03, 0x68, 0xCC, 0x8C, + 0x03, 0x41, 0xCC, 0x87, 0x03, 0x61, 0xCC, 0x87, + 0x03, 0x45, 0xCC, 0xA7, 0x03, 0x65, 0xCC, 0xA7, + 0x05, 0x4F, 0xCC, 0x88, 0xCC, 0x84, 0x05, 0x6F, + 0xCC, 0x88, 0xCC, 0x84, 0x05, 0x4F, 0xCC, 0x83, + 0xCC, 0x84, 0x05, 0x6F, 0xCC, 0x83, 0xCC, 0x84, + 0x03, 0x4F, 0xCC, 0x87, 0x03, 0x6F, 0xCC, 0x87, + // Bytes 480 - 4bf + 0x05, 0x4F, 0xCC, 0x87, 0xCC, 0x84, 0x05, 0x6F, + 0xCC, 0x87, 0xCC, 0x84, 0x03, 0x59, 0xCC, 0x84, + 0x03, 0x79, 0xCC, 0x84, 0x01, 0x68, 0x02, 0xC9, + 0xA6, 0x01, 0x6A, 0x01, 0x72, 0x02, 0xC9, 0xB9, + 0x02, 0xC9, 0xBB, 0x02, 0xCA, 0x81, 0x01, 0x77, + 0x01, 0x79, 0x03, 0x20, 0xCC, 0x86, 0x03, 0x20, + 0xCC, 0x87, 0x03, 0x20, 0xCC, 0x8A, 0x03, 0x20, + 0xCC, 0xA8, 0x03, 0x20, 0xCC, 0x83, 0x03, 0x20, + // Bytes 4c0 - 4ff + 0xCC, 0x8B, 0x02, 0xC9, 0xA3, 0x01, 0x6C, 0x01, + 0x78, 0x02, 0xCA, 0x95, 0x02, 0xCC, 0x80, 0x02, + 0xCC, 0x81, 0x02, 0xCC, 0x93, 0x04, 0xCC, 0x88, + 0xCC, 0x81, 0x02, 0xCA, 0xB9, 0x03, 0x20, 0xCD, + 0x85, 0x01, 0x3B, 0x04, 0xC2, 0xA8, 0xCC, 0x81, + 0x05, 0x20, 0xCC, 0x88, 0xCC, 0x81, 0x04, 0xCE, + 0x91, 0xCC, 0x81, 0x02, 0xC2, 0xB7, 0x04, 0xCE, + 0x95, 0xCC, 0x81, 0x04, 0xCE, 0x97, 0xCC, 0x81, + // Bytes 500 - 53f + 0x04, 0xCE, 0x99, 0xCC, 0x81, 0x04, 0xCE, 0x9F, + 0xCC, 0x81, 0x04, 0xCE, 0xA5, 0xCC, 0x81, 0x04, + 0xCE, 0xA9, 0xCC, 0x81, 0x06, 0xCE, 0xB9, 0xCC, + 0x88, 0xCC, 0x81, 0x04, 0xCE, 0x99, 0xCC, 0x88, + 0x04, 0xCE, 0xA5, 0xCC, 0x88, 0x04, 0xCE, 0xB1, + 0xCC, 0x81, 0x04, 0xCE, 0xB5, 0xCC, 0x81, 0x04, + 0xCE, 0xB7, 0xCC, 0x81, 0x04, 0xCE, 0xB9, 0xCC, + 0x81, 0x06, 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x81, + // Bytes 540 - 57f + 0x04, 0xCE, 0xB9, 0xCC, 0x88, 0x04, 0xCF, 0x85, + 0xCC, 0x88, 0x04, 0xCE, 0xBF, 0xCC, 0x81, 0x04, + 0xCF, 0x85, 0xCC, 0x81, 0x04, 0xCF, 0x89, 0xCC, + 0x81, 0x02, 0xCE, 0xB2, 0x02, 0xCE, 0xB8, 0x02, + 0xCE, 0xA5, 0x04, 0xCF, 0x92, 0xCC, 0x81, 0x04, + 0xCF, 0x92, 0xCC, 0x88, 0x02, 0xCF, 0x86, 0x02, + 0xCF, 0x80, 0x02, 0xCE, 0xBA, 0x02, 0xCF, 0x81, + 0x02, 0xCF, 0x82, 0x02, 0xCE, 0x98, 0x02, 0xCE, + // Bytes 580 - 5bf + 0xB5, 0x02, 0xCE, 0xA3, 0x04, 0xD0, 0x95, 0xCC, + 0x80, 0x04, 0xD0, 0x95, 0xCC, 0x88, 0x04, 0xD0, + 0x93, 0xCC, 0x81, 0x04, 0xD0, 0x86, 0xCC, 0x88, + 0x04, 0xD0, 0x9A, 0xCC, 0x81, 0x04, 0xD0, 0x98, + 0xCC, 0x80, 0x04, 0xD0, 0xA3, 0xCC, 0x86, 0x04, + 0xD0, 0x98, 0xCC, 0x86, 0x04, 0xD0, 0xB8, 0xCC, + 0x86, 0x04, 0xD0, 0xB5, 0xCC, 0x80, 0x04, 0xD0, + 0xB5, 0xCC, 0x88, 0x04, 0xD0, 0xB3, 0xCC, 0x81, + // Bytes 5c0 - 5ff + 0x04, 0xD1, 0x96, 0xCC, 0x88, 0x04, 0xD0, 0xBA, + 0xCC, 0x81, 0x04, 0xD0, 0xB8, 0xCC, 0x80, 0x04, + 0xD1, 0x83, 0xCC, 0x86, 0x04, 0xD1, 0xB4, 0xCC, + 0x8F, 0x04, 0xD1, 0xB5, 0xCC, 0x8F, 0x04, 0xD0, + 0x96, 0xCC, 0x86, 0x04, 0xD0, 0xB6, 0xCC, 0x86, + 0x04, 0xD0, 0x90, 0xCC, 0x86, 0x04, 0xD0, 0xB0, + 0xCC, 0x86, 0x04, 0xD0, 0x90, 0xCC, 0x88, 0x04, + 0xD0, 0xB0, 0xCC, 0x88, 0x04, 0xD0, 0x95, 0xCC, + // Bytes 600 - 63f + 0x86, 0x04, 0xD0, 0xB5, 0xCC, 0x86, 0x04, 0xD3, + 0x98, 0xCC, 0x88, 0x04, 0xD3, 0x99, 0xCC, 0x88, + 0x04, 0xD0, 0x96, 0xCC, 0x88, 0x04, 0xD0, 0xB6, + 0xCC, 0x88, 0x04, 0xD0, 0x97, 0xCC, 0x88, 0x04, + 0xD0, 0xB7, 0xCC, 0x88, 0x04, 0xD0, 0x98, 0xCC, + 0x84, 0x04, 0xD0, 0xB8, 0xCC, 0x84, 0x04, 0xD0, + 0x98, 0xCC, 0x88, 0x04, 0xD0, 0xB8, 0xCC, 0x88, + 0x04, 0xD0, 0x9E, 0xCC, 0x88, 0x04, 0xD0, 0xBE, + // Bytes 640 - 67f + 0xCC, 0x88, 0x04, 0xD3, 0xA8, 0xCC, 0x88, 0x04, + 0xD3, 0xA9, 0xCC, 0x88, 0x04, 0xD0, 0xAD, 0xCC, + 0x88, 0x04, 0xD1, 0x8D, 0xCC, 0x88, 0x04, 0xD0, + 0xA3, 0xCC, 0x84, 0x04, 0xD1, 0x83, 0xCC, 0x84, + 0x04, 0xD0, 0xA3, 0xCC, 0x88, 0x04, 0xD1, 0x83, + 0xCC, 0x88, 0x04, 0xD0, 0xA3, 0xCC, 0x8B, 0x04, + 0xD1, 0x83, 0xCC, 0x8B, 0x04, 0xD0, 0xA7, 0xCC, + 0x88, 0x04, 0xD1, 0x87, 0xCC, 0x88, 0x04, 0xD0, + // Bytes 680 - 6bf + 0xAB, 0xCC, 0x88, 0x04, 0xD1, 0x8B, 0xCC, 0x88, + 0x04, 0xD5, 0xA5, 0xD6, 0x82, 0x04, 0xD8, 0xA7, + 0xD9, 0x93, 0x04, 0xD8, 0xA7, 0xD9, 0x94, 0x04, + 0xD9, 0x88, 0xD9, 0x94, 0x04, 0xD8, 0xA7, 0xD9, + 0x95, 0x04, 0xD9, 0x8A, 0xD9, 0x94, 0x04, 0xD8, + 0xA7, 0xD9, 0xB4, 0x04, 0xD9, 0x88, 0xD9, 0xB4, + 0x04, 0xDB, 0x87, 0xD9, 0xB4, 0x04, 0xD9, 0x8A, + 0xD9, 0xB4, 0x04, 0xDB, 0x95, 0xD9, 0x94, 0x04, + // Bytes 6c0 - 6ff + 0xDB, 0x81, 0xD9, 0x94, 0x04, 0xDB, 0x92, 0xD9, + 0x94, 0x06, 0xE0, 0xA4, 0xA8, 0xE0, 0xA4, 0xBC, + 0x06, 0xE0, 0xA4, 0xB0, 0xE0, 0xA4, 0xBC, 0x06, + 0xE0, 0xA4, 0xB3, 0xE0, 0xA4, 0xBC, 0x06, 0xE0, + 0xA4, 0x95, 0xE0, 0xA4, 0xBC, 0x06, 0xE0, 0xA4, + 0x96, 0xE0, 0xA4, 0xBC, 0x06, 0xE0, 0xA4, 0x97, + 0xE0, 0xA4, 0xBC, 0x06, 0xE0, 0xA4, 0x9C, 0xE0, + 0xA4, 0xBC, 0x06, 0xE0, 0xA4, 0xA1, 0xE0, 0xA4, + // Bytes 700 - 73f + 0xBC, 0x06, 0xE0, 0xA4, 0xA2, 0xE0, 0xA4, 0xBC, + 0x06, 0xE0, 0xA4, 0xAB, 0xE0, 0xA4, 0xBC, 0x06, + 0xE0, 0xA4, 0xAF, 0xE0, 0xA4, 0xBC, 0x06, 0xE0, + 0xA7, 0x87, 0xE0, 0xA6, 0xBE, 0x06, 0xE0, 0xA7, + 0x87, 0xE0, 0xA7, 0x97, 0x06, 0xE0, 0xA6, 0xA1, + 0xE0, 0xA6, 0xBC, 0x06, 0xE0, 0xA6, 0xA2, 0xE0, + 0xA6, 0xBC, 0x06, 0xE0, 0xA6, 0xAF, 0xE0, 0xA6, + 0xBC, 0x06, 0xE0, 0xA8, 0xB2, 0xE0, 0xA8, 0xBC, + // Bytes 740 - 77f + 0x06, 0xE0, 0xA8, 0xB8, 0xE0, 0xA8, 0xBC, 0x06, + 0xE0, 0xA8, 0x96, 0xE0, 0xA8, 0xBC, 0x06, 0xE0, + 0xA8, 0x97, 0xE0, 0xA8, 0xBC, 0x06, 0xE0, 0xA8, + 0x9C, 0xE0, 0xA8, 0xBC, 0x06, 0xE0, 0xA8, 0xAB, + 0xE0, 0xA8, 0xBC, 0x06, 0xE0, 0xAD, 0x87, 0xE0, + 0xAD, 0x96, 0x06, 0xE0, 0xAD, 0x87, 0xE0, 0xAC, + 0xBE, 0x06, 0xE0, 0xAD, 0x87, 0xE0, 0xAD, 0x97, + 0x06, 0xE0, 0xAC, 0xA1, 0xE0, 0xAC, 0xBC, 0x06, + // Bytes 780 - 7bf + 0xE0, 0xAC, 0xA2, 0xE0, 0xAC, 0xBC, 0x06, 0xE0, + 0xAE, 0x92, 0xE0, 0xAF, 0x97, 0x06, 0xE0, 0xAF, + 0x86, 0xE0, 0xAE, 0xBE, 0x06, 0xE0, 0xAF, 0x87, + 0xE0, 0xAE, 0xBE, 0x06, 0xE0, 0xAF, 0x86, 0xE0, + 0xAF, 0x97, 0x06, 0xE0, 0xB1, 0x86, 0xE0, 0xB1, + 0x96, 0x06, 0xE0, 0xB2, 0xBF, 0xE0, 0xB3, 0x95, + 0x06, 0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x95, 0x06, + 0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x96, 0x06, 0xE0, + // Bytes 7c0 - 7ff + 0xB3, 0x86, 0xE0, 0xB3, 0x82, 0x09, 0xE0, 0xB3, + 0x86, 0xE0, 0xB3, 0x82, 0xE0, 0xB3, 0x95, 0x06, + 0xE0, 0xB5, 0x86, 0xE0, 0xB4, 0xBE, 0x06, 0xE0, + 0xB5, 0x87, 0xE0, 0xB4, 0xBE, 0x06, 0xE0, 0xB5, + 0x86, 0xE0, 0xB5, 0x97, 0x06, 0xE0, 0xB7, 0x99, + 0xE0, 0xB7, 0x8A, 0x06, 0xE0, 0xB7, 0x99, 0xE0, + 0xB7, 0x8F, 0x09, 0xE0, 0xB7, 0x99, 0xE0, 0xB7, + 0x8F, 0xE0, 0xB7, 0x8A, 0x06, 0xE0, 0xB7, 0x99, + // Bytes 800 - 83f + 0xE0, 0xB7, 0x9F, 0x06, 0xE0, 0xB9, 0x8D, 0xE0, + 0xB8, 0xB2, 0x06, 0xE0, 0xBB, 0x8D, 0xE0, 0xBA, + 0xB2, 0x06, 0xE0, 0xBA, 0xAB, 0xE0, 0xBA, 0x99, + 0x06, 0xE0, 0xBA, 0xAB, 0xE0, 0xBA, 0xA1, 0x03, + 0xE0, 0xBC, 0x8B, 0x06, 0xE0, 0xBD, 0x82, 0xE0, + 0xBE, 0xB7, 0x06, 0xE0, 0xBD, 0x8C, 0xE0, 0xBE, + 0xB7, 0x06, 0xE0, 0xBD, 0x91, 0xE0, 0xBE, 0xB7, + 0x06, 0xE0, 0xBD, 0x96, 0xE0, 0xBE, 0xB7, 0x06, + // Bytes 840 - 87f + 0xE0, 0xBD, 0x9B, 0xE0, 0xBE, 0xB7, 0x06, 0xE0, + 0xBD, 0x80, 0xE0, 0xBE, 0xB5, 0x06, 0xE0, 0xBD, + 0xB1, 0xE0, 0xBD, 0xB2, 0x06, 0xE0, 0xBD, 0xB1, + 0xE0, 0xBD, 0xB4, 0x06, 0xE0, 0xBE, 0xB2, 0xE0, + 0xBE, 0x80, 0x09, 0xE0, 0xBE, 0xB2, 0xE0, 0xBD, + 0xB1, 0xE0, 0xBE, 0x80, 0x06, 0xE0, 0xBE, 0xB3, + 0xE0, 0xBE, 0x80, 0x09, 0xE0, 0xBE, 0xB3, 0xE0, + 0xBD, 0xB1, 0xE0, 0xBE, 0x80, 0x06, 0xE0, 0xBD, + // Bytes 880 - 8bf + 0xB1, 0xE0, 0xBE, 0x80, 0x06, 0xE0, 0xBE, 0x92, + 0xE0, 0xBE, 0xB7, 0x06, 0xE0, 0xBE, 0x9C, 0xE0, + 0xBE, 0xB7, 0x06, 0xE0, 0xBE, 0xA1, 0xE0, 0xBE, + 0xB7, 0x06, 0xE0, 0xBE, 0xA6, 0xE0, 0xBE, 0xB7, + 0x06, 0xE0, 0xBE, 0xAB, 0xE0, 0xBE, 0xB7, 0x06, + 0xE0, 0xBE, 0x90, 0xE0, 0xBE, 0xB5, 0x06, 0xE1, + 0x80, 0xA5, 0xE1, 0x80, 0xAE, 0x03, 0xE1, 0x83, + 0x9C, 0x06, 0xE1, 0xAC, 0x85, 0xE1, 0xAC, 0xB5, + // Bytes 8c0 - 8ff + 0x06, 0xE1, 0xAC, 0x87, 0xE1, 0xAC, 0xB5, 0x06, + 0xE1, 0xAC, 0x89, 0xE1, 0xAC, 0xB5, 0x06, 0xE1, + 0xAC, 0x8B, 0xE1, 0xAC, 0xB5, 0x06, 0xE1, 0xAC, + 0x8D, 0xE1, 0xAC, 0xB5, 0x06, 0xE1, 0xAC, 0x91, + 0xE1, 0xAC, 0xB5, 0x06, 0xE1, 0xAC, 0xBA, 0xE1, + 0xAC, 0xB5, 0x06, 0xE1, 0xAC, 0xBC, 0xE1, 0xAC, + 0xB5, 0x06, 0xE1, 0xAC, 0xBE, 0xE1, 0xAC, 0xB5, + 0x06, 0xE1, 0xAC, 0xBF, 0xE1, 0xAC, 0xB5, 0x06, + // Bytes 900 - 93f + 0xE1, 0xAD, 0x82, 0xE1, 0xAC, 0xB5, 0x01, 0x41, + 0x02, 0xC3, 0x86, 0x01, 0x42, 0x01, 0x44, 0x01, + 0x45, 0x02, 0xC6, 0x8E, 0x01, 0x47, 0x01, 0x48, + 0x01, 0x49, 0x01, 0x4A, 0x01, 0x4B, 0x01, 0x4C, + 0x01, 0x4D, 0x01, 0x4E, 0x01, 0x4F, 0x02, 0xC8, + 0xA2, 0x01, 0x50, 0x01, 0x52, 0x01, 0x54, 0x01, + 0x55, 0x01, 0x57, 0x02, 0xC9, 0x90, 0x02, 0xC9, + 0x91, 0x03, 0xE1, 0xB4, 0x82, 0x01, 0x62, 0x01, + // Bytes 940 - 97f + 0x64, 0x01, 0x65, 0x02, 0xC9, 0x99, 0x02, 0xC9, + 0x9B, 0x02, 0xC9, 0x9C, 0x01, 0x67, 0x01, 0x6B, + 0x01, 0x6D, 0x02, 0xC5, 0x8B, 0x02, 0xC9, 0x94, + 0x03, 0xE1, 0xB4, 0x96, 0x03, 0xE1, 0xB4, 0x97, + 0x01, 0x70, 0x01, 0x74, 0x01, 0x75, 0x03, 0xE1, + 0xB4, 0x9D, 0x02, 0xC9, 0xAF, 0x01, 0x76, 0x03, + 0xE1, 0xB4, 0xA5, 0x02, 0xCE, 0xB3, 0x02, 0xCE, + 0xB4, 0x02, 0xCF, 0x87, 0x01, 0x69, 0x02, 0xD0, + // Bytes 980 - 9bf + 0xBD, 0x02, 0xC9, 0x92, 0x01, 0x63, 0x02, 0xC9, + 0x95, 0x02, 0xC3, 0xB0, 0x01, 0x66, 0x02, 0xC9, + 0x9F, 0x02, 0xC9, 0xA1, 0x02, 0xC9, 0xA5, 0x02, + 0xC9, 0xA8, 0x02, 0xC9, 0xA9, 0x02, 0xC9, 0xAA, + 0x03, 0xE1, 0xB5, 0xBB, 0x02, 0xCA, 0x9D, 0x02, + 0xC9, 0xAD, 0x03, 0xE1, 0xB6, 0x85, 0x02, 0xCA, + 0x9F, 0x02, 0xC9, 0xB1, 0x02, 0xC9, 0xB0, 0x02, + 0xC9, 0xB2, 0x02, 0xC9, 0xB3, 0x02, 0xC9, 0xB4, + // Bytes 9c0 - 9ff + 0x02, 0xC9, 0xB5, 0x02, 0xC9, 0xB8, 0x02, 0xCA, + 0x82, 0x02, 0xCA, 0x83, 0x02, 0xC6, 0xAB, 0x02, + 0xCA, 0x89, 0x02, 0xCA, 0x8A, 0x03, 0xE1, 0xB4, + 0x9C, 0x02, 0xCA, 0x8B, 0x02, 0xCA, 0x8C, 0x01, + 0x7A, 0x02, 0xCA, 0x90, 0x02, 0xCA, 0x91, 0x02, + 0xCA, 0x92, 0x03, 0x41, 0xCC, 0xA5, 0x03, 0x61, + 0xCC, 0xA5, 0x03, 0x42, 0xCC, 0x87, 0x03, 0x62, + 0xCC, 0x87, 0x03, 0x42, 0xCC, 0xA3, 0x03, 0x62, + // Bytes a00 - a3f + 0xCC, 0xA3, 0x03, 0x42, 0xCC, 0xB1, 0x03, 0x62, + 0xCC, 0xB1, 0x05, 0x43, 0xCC, 0xA7, 0xCC, 0x81, + 0x05, 0x63, 0xCC, 0xA7, 0xCC, 0x81, 0x03, 0x44, + 0xCC, 0x87, 0x03, 0x64, 0xCC, 0x87, 0x03, 0x44, + 0xCC, 0xA3, 0x03, 0x64, 0xCC, 0xA3, 0x03, 0x44, + 0xCC, 0xB1, 0x03, 0x64, 0xCC, 0xB1, 0x03, 0x44, + 0xCC, 0xA7, 0x03, 0x64, 0xCC, 0xA7, 0x03, 0x44, + 0xCC, 0xAD, 0x03, 0x64, 0xCC, 0xAD, 0x05, 0x45, + // Bytes a40 - a7f + 0xCC, 0x84, 0xCC, 0x80, 0x05, 0x65, 0xCC, 0x84, + 0xCC, 0x80, 0x05, 0x45, 0xCC, 0x84, 0xCC, 0x81, + 0x05, 0x65, 0xCC, 0x84, 0xCC, 0x81, 0x03, 0x45, + 0xCC, 0xAD, 0x03, 0x65, 0xCC, 0xAD, 0x03, 0x45, + 0xCC, 0xB0, 0x03, 0x65, 0xCC, 0xB0, 0x05, 0x45, + 0xCC, 0xA7, 0xCC, 0x86, 0x05, 0x65, 0xCC, 0xA7, + 0xCC, 0x86, 0x03, 0x46, 0xCC, 0x87, 0x03, 0x66, + 0xCC, 0x87, 0x03, 0x47, 0xCC, 0x84, 0x03, 0x67, + // Bytes a80 - abf + 0xCC, 0x84, 0x03, 0x48, 0xCC, 0x87, 0x03, 0x68, + 0xCC, 0x87, 0x03, 0x48, 0xCC, 0xA3, 0x03, 0x68, + 0xCC, 0xA3, 0x03, 0x48, 0xCC, 0x88, 0x03, 0x68, + 0xCC, 0x88, 0x03, 0x48, 0xCC, 0xA7, 0x03, 0x68, + 0xCC, 0xA7, 0x03, 0x48, 0xCC, 0xAE, 0x03, 0x68, + 0xCC, 0xAE, 0x03, 0x49, 0xCC, 0xB0, 0x03, 0x69, + 0xCC, 0xB0, 0x05, 0x49, 0xCC, 0x88, 0xCC, 0x81, + 0x05, 0x69, 0xCC, 0x88, 0xCC, 0x81, 0x03, 0x4B, + // Bytes ac0 - aff + 0xCC, 0x81, 0x03, 0x6B, 0xCC, 0x81, 0x03, 0x4B, + 0xCC, 0xA3, 0x03, 0x6B, 0xCC, 0xA3, 0x03, 0x4B, + 0xCC, 0xB1, 0x03, 0x6B, 0xCC, 0xB1, 0x03, 0x4C, + 0xCC, 0xA3, 0x03, 0x6C, 0xCC, 0xA3, 0x05, 0x4C, + 0xCC, 0xA3, 0xCC, 0x84, 0x05, 0x6C, 0xCC, 0xA3, + 0xCC, 0x84, 0x03, 0x4C, 0xCC, 0xB1, 0x03, 0x6C, + 0xCC, 0xB1, 0x03, 0x4C, 0xCC, 0xAD, 0x03, 0x6C, + 0xCC, 0xAD, 0x03, 0x4D, 0xCC, 0x81, 0x03, 0x6D, + // Bytes b00 - b3f + 0xCC, 0x81, 0x03, 0x4D, 0xCC, 0x87, 0x03, 0x6D, + 0xCC, 0x87, 0x03, 0x4D, 0xCC, 0xA3, 0x03, 0x6D, + 0xCC, 0xA3, 0x03, 0x4E, 0xCC, 0x87, 0x03, 0x6E, + 0xCC, 0x87, 0x03, 0x4E, 0xCC, 0xA3, 0x03, 0x6E, + 0xCC, 0xA3, 0x03, 0x4E, 0xCC, 0xB1, 0x03, 0x6E, + 0xCC, 0xB1, 0x03, 0x4E, 0xCC, 0xAD, 0x03, 0x6E, + 0xCC, 0xAD, 0x05, 0x4F, 0xCC, 0x83, 0xCC, 0x81, + 0x05, 0x6F, 0xCC, 0x83, 0xCC, 0x81, 0x05, 0x4F, + // Bytes b40 - b7f + 0xCC, 0x83, 0xCC, 0x88, 0x05, 0x6F, 0xCC, 0x83, + 0xCC, 0x88, 0x05, 0x4F, 0xCC, 0x84, 0xCC, 0x80, + 0x05, 0x6F, 0xCC, 0x84, 0xCC, 0x80, 0x05, 0x4F, + 0xCC, 0x84, 0xCC, 0x81, 0x05, 0x6F, 0xCC, 0x84, + 0xCC, 0x81, 0x03, 0x50, 0xCC, 0x81, 0x03, 0x70, + 0xCC, 0x81, 0x03, 0x50, 0xCC, 0x87, 0x03, 0x70, + 0xCC, 0x87, 0x03, 0x52, 0xCC, 0x87, 0x03, 0x72, + 0xCC, 0x87, 0x03, 0x52, 0xCC, 0xA3, 0x03, 0x72, + // Bytes b80 - bbf + 0xCC, 0xA3, 0x05, 0x52, 0xCC, 0xA3, 0xCC, 0x84, + 0x05, 0x72, 0xCC, 0xA3, 0xCC, 0x84, 0x03, 0x52, + 0xCC, 0xB1, 0x03, 0x72, 0xCC, 0xB1, 0x03, 0x53, + 0xCC, 0x87, 0x03, 0x73, 0xCC, 0x87, 0x03, 0x53, + 0xCC, 0xA3, 0x03, 0x73, 0xCC, 0xA3, 0x05, 0x53, + 0xCC, 0x81, 0xCC, 0x87, 0x05, 0x73, 0xCC, 0x81, + 0xCC, 0x87, 0x05, 0x53, 0xCC, 0x8C, 0xCC, 0x87, + 0x05, 0x73, 0xCC, 0x8C, 0xCC, 0x87, 0x05, 0x53, + // Bytes bc0 - bff + 0xCC, 0xA3, 0xCC, 0x87, 0x05, 0x73, 0xCC, 0xA3, + 0xCC, 0x87, 0x03, 0x54, 0xCC, 0x87, 0x03, 0x74, + 0xCC, 0x87, 0x03, 0x54, 0xCC, 0xA3, 0x03, 0x74, + 0xCC, 0xA3, 0x03, 0x54, 0xCC, 0xB1, 0x03, 0x74, + 0xCC, 0xB1, 0x03, 0x54, 0xCC, 0xAD, 0x03, 0x74, + 0xCC, 0xAD, 0x03, 0x55, 0xCC, 0xA4, 0x03, 0x75, + 0xCC, 0xA4, 0x03, 0x55, 0xCC, 0xB0, 0x03, 0x75, + 0xCC, 0xB0, 0x03, 0x55, 0xCC, 0xAD, 0x03, 0x75, + // Bytes c00 - c3f + 0xCC, 0xAD, 0x05, 0x55, 0xCC, 0x83, 0xCC, 0x81, + 0x05, 0x75, 0xCC, 0x83, 0xCC, 0x81, 0x05, 0x55, + 0xCC, 0x84, 0xCC, 0x88, 0x05, 0x75, 0xCC, 0x84, + 0xCC, 0x88, 0x03, 0x56, 0xCC, 0x83, 0x03, 0x76, + 0xCC, 0x83, 0x03, 0x56, 0xCC, 0xA3, 0x03, 0x76, + 0xCC, 0xA3, 0x03, 0x57, 0xCC, 0x80, 0x03, 0x77, + 0xCC, 0x80, 0x03, 0x57, 0xCC, 0x81, 0x03, 0x77, + 0xCC, 0x81, 0x03, 0x57, 0xCC, 0x88, 0x03, 0x77, + // Bytes c40 - c7f + 0xCC, 0x88, 0x03, 0x57, 0xCC, 0x87, 0x03, 0x77, + 0xCC, 0x87, 0x03, 0x57, 0xCC, 0xA3, 0x03, 0x77, + 0xCC, 0xA3, 0x03, 0x58, 0xCC, 0x87, 0x03, 0x78, + 0xCC, 0x87, 0x03, 0x58, 0xCC, 0x88, 0x03, 0x78, + 0xCC, 0x88, 0x03, 0x59, 0xCC, 0x87, 0x03, 0x79, + 0xCC, 0x87, 0x03, 0x5A, 0xCC, 0x82, 0x03, 0x7A, + 0xCC, 0x82, 0x03, 0x5A, 0xCC, 0xA3, 0x03, 0x7A, + 0xCC, 0xA3, 0x03, 0x5A, 0xCC, 0xB1, 0x03, 0x7A, + // Bytes c80 - cbf + 0xCC, 0xB1, 0x03, 0x68, 0xCC, 0xB1, 0x03, 0x74, + 0xCC, 0x88, 0x03, 0x77, 0xCC, 0x8A, 0x03, 0x79, + 0xCC, 0x8A, 0x03, 0x61, 0xCA, 0xBE, 0x04, 0xC5, + 0xBF, 0xCC, 0x87, 0x03, 0x41, 0xCC, 0xA3, 0x03, + 0x61, 0xCC, 0xA3, 0x03, 0x41, 0xCC, 0x89, 0x03, + 0x61, 0xCC, 0x89, 0x05, 0x41, 0xCC, 0x82, 0xCC, + 0x81, 0x05, 0x61, 0xCC, 0x82, 0xCC, 0x81, 0x05, + 0x41, 0xCC, 0x82, 0xCC, 0x80, 0x05, 0x61, 0xCC, + // Bytes cc0 - cff + 0x82, 0xCC, 0x80, 0x05, 0x41, 0xCC, 0x82, 0xCC, + 0x89, 0x05, 0x61, 0xCC, 0x82, 0xCC, 0x89, 0x05, + 0x41, 0xCC, 0x82, 0xCC, 0x83, 0x05, 0x61, 0xCC, + 0x82, 0xCC, 0x83, 0x05, 0x41, 0xCC, 0xA3, 0xCC, + 0x82, 0x05, 0x61, 0xCC, 0xA3, 0xCC, 0x82, 0x05, + 0x41, 0xCC, 0x86, 0xCC, 0x81, 0x05, 0x61, 0xCC, + 0x86, 0xCC, 0x81, 0x05, 0x41, 0xCC, 0x86, 0xCC, + 0x80, 0x05, 0x61, 0xCC, 0x86, 0xCC, 0x80, 0x05, + // Bytes d00 - d3f + 0x41, 0xCC, 0x86, 0xCC, 0x89, 0x05, 0x61, 0xCC, + 0x86, 0xCC, 0x89, 0x05, 0x41, 0xCC, 0x86, 0xCC, + 0x83, 0x05, 0x61, 0xCC, 0x86, 0xCC, 0x83, 0x05, + 0x41, 0xCC, 0xA3, 0xCC, 0x86, 0x05, 0x61, 0xCC, + 0xA3, 0xCC, 0x86, 0x03, 0x45, 0xCC, 0xA3, 0x03, + 0x65, 0xCC, 0xA3, 0x03, 0x45, 0xCC, 0x89, 0x03, + 0x65, 0xCC, 0x89, 0x03, 0x45, 0xCC, 0x83, 0x03, + 0x65, 0xCC, 0x83, 0x05, 0x45, 0xCC, 0x82, 0xCC, + // Bytes d40 - d7f + 0x81, 0x05, 0x65, 0xCC, 0x82, 0xCC, 0x81, 0x05, + 0x45, 0xCC, 0x82, 0xCC, 0x80, 0x05, 0x65, 0xCC, + 0x82, 0xCC, 0x80, 0x05, 0x45, 0xCC, 0x82, 0xCC, + 0x89, 0x05, 0x65, 0xCC, 0x82, 0xCC, 0x89, 0x05, + 0x45, 0xCC, 0x82, 0xCC, 0x83, 0x05, 0x65, 0xCC, + 0x82, 0xCC, 0x83, 0x05, 0x45, 0xCC, 0xA3, 0xCC, + 0x82, 0x05, 0x65, 0xCC, 0xA3, 0xCC, 0x82, 0x03, + 0x49, 0xCC, 0x89, 0x03, 0x69, 0xCC, 0x89, 0x03, + // Bytes d80 - dbf + 0x49, 0xCC, 0xA3, 0x03, 0x69, 0xCC, 0xA3, 0x03, + 0x4F, 0xCC, 0xA3, 0x03, 0x6F, 0xCC, 0xA3, 0x03, + 0x4F, 0xCC, 0x89, 0x03, 0x6F, 0xCC, 0x89, 0x05, + 0x4F, 0xCC, 0x82, 0xCC, 0x81, 0x05, 0x6F, 0xCC, + 0x82, 0xCC, 0x81, 0x05, 0x4F, 0xCC, 0x82, 0xCC, + 0x80, 0x05, 0x6F, 0xCC, 0x82, 0xCC, 0x80, 0x05, + 0x4F, 0xCC, 0x82, 0xCC, 0x89, 0x05, 0x6F, 0xCC, + 0x82, 0xCC, 0x89, 0x05, 0x4F, 0xCC, 0x82, 0xCC, + // Bytes dc0 - dff + 0x83, 0x05, 0x6F, 0xCC, 0x82, 0xCC, 0x83, 0x05, + 0x4F, 0xCC, 0xA3, 0xCC, 0x82, 0x05, 0x6F, 0xCC, + 0xA3, 0xCC, 0x82, 0x05, 0x4F, 0xCC, 0x9B, 0xCC, + 0x81, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0x81, 0x05, + 0x4F, 0xCC, 0x9B, 0xCC, 0x80, 0x05, 0x6F, 0xCC, + 0x9B, 0xCC, 0x80, 0x05, 0x4F, 0xCC, 0x9B, 0xCC, + 0x89, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0x89, 0x05, + 0x4F, 0xCC, 0x9B, 0xCC, 0x83, 0x05, 0x6F, 0xCC, + // Bytes e00 - e3f + 0x9B, 0xCC, 0x83, 0x05, 0x4F, 0xCC, 0x9B, 0xCC, + 0xA3, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0xA3, 0x03, + 0x55, 0xCC, 0xA3, 0x03, 0x75, 0xCC, 0xA3, 0x03, + 0x55, 0xCC, 0x89, 0x03, 0x75, 0xCC, 0x89, 0x05, + 0x55, 0xCC, 0x9B, 0xCC, 0x81, 0x05, 0x75, 0xCC, + 0x9B, 0xCC, 0x81, 0x05, 0x55, 0xCC, 0x9B, 0xCC, + 0x80, 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0x80, 0x05, + 0x55, 0xCC, 0x9B, 0xCC, 0x89, 0x05, 0x75, 0xCC, + // Bytes e40 - e7f + 0x9B, 0xCC, 0x89, 0x05, 0x55, 0xCC, 0x9B, 0xCC, + 0x83, 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0x83, 0x05, + 0x55, 0xCC, 0x9B, 0xCC, 0xA3, 0x05, 0x75, 0xCC, + 0x9B, 0xCC, 0xA3, 0x03, 0x59, 0xCC, 0x80, 0x03, + 0x79, 0xCC, 0x80, 0x03, 0x59, 0xCC, 0xA3, 0x03, + 0x79, 0xCC, 0xA3, 0x03, 0x59, 0xCC, 0x89, 0x03, + 0x79, 0xCC, 0x89, 0x03, 0x59, 0xCC, 0x83, 0x03, + 0x79, 0xCC, 0x83, 0x04, 0xCE, 0xB1, 0xCC, 0x93, + // Bytes e80 - ebf + 0x04, 0xCE, 0xB1, 0xCC, 0x94, 0x06, 0xCE, 0xB1, + 0xCC, 0x93, 0xCC, 0x80, 0x06, 0xCE, 0xB1, 0xCC, + 0x94, 0xCC, 0x80, 0x06, 0xCE, 0xB1, 0xCC, 0x93, + 0xCC, 0x81, 0x06, 0xCE, 0xB1, 0xCC, 0x94, 0xCC, + 0x81, 0x06, 0xCE, 0xB1, 0xCC, 0x93, 0xCD, 0x82, + 0x06, 0xCE, 0xB1, 0xCC, 0x94, 0xCD, 0x82, 0x04, + 0xCE, 0x91, 0xCC, 0x93, 0x04, 0xCE, 0x91, 0xCC, + 0x94, 0x06, 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x80, + // Bytes ec0 - eff + 0x06, 0xCE, 0x91, 0xCC, 0x94, 0xCC, 0x80, 0x06, + 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x81, 0x06, 0xCE, + 0x91, 0xCC, 0x94, 0xCC, 0x81, 0x06, 0xCE, 0x91, + 0xCC, 0x93, 0xCD, 0x82, 0x06, 0xCE, 0x91, 0xCC, + 0x94, 0xCD, 0x82, 0x04, 0xCE, 0xB5, 0xCC, 0x93, + 0x04, 0xCE, 0xB5, 0xCC, 0x94, 0x06, 0xCE, 0xB5, + 0xCC, 0x93, 0xCC, 0x80, 0x06, 0xCE, 0xB5, 0xCC, + 0x94, 0xCC, 0x80, 0x06, 0xCE, 0xB5, 0xCC, 0x93, + // Bytes f00 - f3f + 0xCC, 0x81, 0x06, 0xCE, 0xB5, 0xCC, 0x94, 0xCC, + 0x81, 0x04, 0xCE, 0x95, 0xCC, 0x93, 0x04, 0xCE, + 0x95, 0xCC, 0x94, 0x06, 0xCE, 0x95, 0xCC, 0x93, + 0xCC, 0x80, 0x06, 0xCE, 0x95, 0xCC, 0x94, 0xCC, + 0x80, 0x06, 0xCE, 0x95, 0xCC, 0x93, 0xCC, 0x81, + 0x06, 0xCE, 0x95, 0xCC, 0x94, 0xCC, 0x81, 0x04, + 0xCE, 0xB7, 0xCC, 0x93, 0x04, 0xCE, 0xB7, 0xCC, + 0x94, 0x06, 0xCE, 0xB7, 0xCC, 0x93, 0xCC, 0x80, + // Bytes f40 - f7f + 0x06, 0xCE, 0xB7, 0xCC, 0x94, 0xCC, 0x80, 0x06, + 0xCE, 0xB7, 0xCC, 0x93, 0xCC, 0x81, 0x06, 0xCE, + 0xB7, 0xCC, 0x94, 0xCC, 0x81, 0x06, 0xCE, 0xB7, + 0xCC, 0x93, 0xCD, 0x82, 0x06, 0xCE, 0xB7, 0xCC, + 0x94, 0xCD, 0x82, 0x04, 0xCE, 0x97, 0xCC, 0x93, + 0x04, 0xCE, 0x97, 0xCC, 0x94, 0x06, 0xCE, 0x97, + 0xCC, 0x93, 0xCC, 0x80, 0x06, 0xCE, 0x97, 0xCC, + 0x94, 0xCC, 0x80, 0x06, 0xCE, 0x97, 0xCC, 0x93, + // Bytes f80 - fbf + 0xCC, 0x81, 0x06, 0xCE, 0x97, 0xCC, 0x94, 0xCC, + 0x81, 0x06, 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x82, + 0x06, 0xCE, 0x97, 0xCC, 0x94, 0xCD, 0x82, 0x04, + 0xCE, 0xB9, 0xCC, 0x93, 0x04, 0xCE, 0xB9, 0xCC, + 0x94, 0x06, 0xCE, 0xB9, 0xCC, 0x93, 0xCC, 0x80, + 0x06, 0xCE, 0xB9, 0xCC, 0x94, 0xCC, 0x80, 0x06, + 0xCE, 0xB9, 0xCC, 0x93, 0xCC, 0x81, 0x06, 0xCE, + 0xB9, 0xCC, 0x94, 0xCC, 0x81, 0x06, 0xCE, 0xB9, + // Bytes fc0 - fff + 0xCC, 0x93, 0xCD, 0x82, 0x06, 0xCE, 0xB9, 0xCC, + 0x94, 0xCD, 0x82, 0x04, 0xCE, 0x99, 0xCC, 0x93, + 0x04, 0xCE, 0x99, 0xCC, 0x94, 0x06, 0xCE, 0x99, + 0xCC, 0x93, 0xCC, 0x80, 0x06, 0xCE, 0x99, 0xCC, + 0x94, 0xCC, 0x80, 0x06, 0xCE, 0x99, 0xCC, 0x93, + 0xCC, 0x81, 0x06, 0xCE, 0x99, 0xCC, 0x94, 0xCC, + 0x81, 0x06, 0xCE, 0x99, 0xCC, 0x93, 0xCD, 0x82, + 0x06, 0xCE, 0x99, 0xCC, 0x94, 0xCD, 0x82, 0x04, + // Bytes 1000 - 103f + 0xCE, 0xBF, 0xCC, 0x93, 0x04, 0xCE, 0xBF, 0xCC, + 0x94, 0x06, 0xCE, 0xBF, 0xCC, 0x93, 0xCC, 0x80, + 0x06, 0xCE, 0xBF, 0xCC, 0x94, 0xCC, 0x80, 0x06, + 0xCE, 0xBF, 0xCC, 0x93, 0xCC, 0x81, 0x06, 0xCE, + 0xBF, 0xCC, 0x94, 0xCC, 0x81, 0x04, 0xCE, 0x9F, + 0xCC, 0x93, 0x04, 0xCE, 0x9F, 0xCC, 0x94, 0x06, + 0xCE, 0x9F, 0xCC, 0x93, 0xCC, 0x80, 0x06, 0xCE, + 0x9F, 0xCC, 0x94, 0xCC, 0x80, 0x06, 0xCE, 0x9F, + // Bytes 1040 - 107f + 0xCC, 0x93, 0xCC, 0x81, 0x06, 0xCE, 0x9F, 0xCC, + 0x94, 0xCC, 0x81, 0x04, 0xCF, 0x85, 0xCC, 0x93, + 0x04, 0xCF, 0x85, 0xCC, 0x94, 0x06, 0xCF, 0x85, + 0xCC, 0x93, 0xCC, 0x80, 0x06, 0xCF, 0x85, 0xCC, + 0x94, 0xCC, 0x80, 0x06, 0xCF, 0x85, 0xCC, 0x93, + 0xCC, 0x81, 0x06, 0xCF, 0x85, 0xCC, 0x94, 0xCC, + 0x81, 0x06, 0xCF, 0x85, 0xCC, 0x93, 0xCD, 0x82, + 0x06, 0xCF, 0x85, 0xCC, 0x94, 0xCD, 0x82, 0x04, + // Bytes 1080 - 10bf + 0xCE, 0xA5, 0xCC, 0x94, 0x06, 0xCE, 0xA5, 0xCC, + 0x94, 0xCC, 0x80, 0x06, 0xCE, 0xA5, 0xCC, 0x94, + 0xCC, 0x81, 0x06, 0xCE, 0xA5, 0xCC, 0x94, 0xCD, + 0x82, 0x04, 0xCF, 0x89, 0xCC, 0x93, 0x04, 0xCF, + 0x89, 0xCC, 0x94, 0x06, 0xCF, 0x89, 0xCC, 0x93, + 0xCC, 0x80, 0x06, 0xCF, 0x89, 0xCC, 0x94, 0xCC, + 0x80, 0x06, 0xCF, 0x89, 0xCC, 0x93, 0xCC, 0x81, + 0x06, 0xCF, 0x89, 0xCC, 0x94, 0xCC, 0x81, 0x06, + // Bytes 10c0 - 10ff + 0xCF, 0x89, 0xCC, 0x93, 0xCD, 0x82, 0x06, 0xCF, + 0x89, 0xCC, 0x94, 0xCD, 0x82, 0x04, 0xCE, 0xA9, + 0xCC, 0x93, 0x04, 0xCE, 0xA9, 0xCC, 0x94, 0x06, + 0xCE, 0xA9, 0xCC, 0x93, 0xCC, 0x80, 0x06, 0xCE, + 0xA9, 0xCC, 0x94, 0xCC, 0x80, 0x06, 0xCE, 0xA9, + 0xCC, 0x93, 0xCC, 0x81, 0x06, 0xCE, 0xA9, 0xCC, + 0x94, 0xCC, 0x81, 0x06, 0xCE, 0xA9, 0xCC, 0x93, + 0xCD, 0x82, 0x06, 0xCE, 0xA9, 0xCC, 0x94, 0xCD, + // Bytes 1100 - 113f + 0x82, 0x04, 0xCE, 0xB1, 0xCC, 0x80, 0x04, 0xCE, + 0xB5, 0xCC, 0x80, 0x04, 0xCE, 0xB7, 0xCC, 0x80, + 0x04, 0xCE, 0xB9, 0xCC, 0x80, 0x04, 0xCE, 0xBF, + 0xCC, 0x80, 0x04, 0xCF, 0x85, 0xCC, 0x80, 0x04, + 0xCF, 0x89, 0xCC, 0x80, 0x06, 0xCE, 0xB1, 0xCC, + 0x93, 0xCD, 0x85, 0x06, 0xCE, 0xB1, 0xCC, 0x94, + 0xCD, 0x85, 0x08, 0xCE, 0xB1, 0xCC, 0x93, 0xCC, + 0x80, 0xCD, 0x85, 0x08, 0xCE, 0xB1, 0xCC, 0x94, + // Bytes 1140 - 117f + 0xCC, 0x80, 0xCD, 0x85, 0x08, 0xCE, 0xB1, 0xCC, + 0x93, 0xCC, 0x81, 0xCD, 0x85, 0x08, 0xCE, 0xB1, + 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85, 0x08, 0xCE, + 0xB1, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85, 0x08, + 0xCE, 0xB1, 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, + 0x06, 0xCE, 0x91, 0xCC, 0x93, 0xCD, 0x85, 0x06, + 0xCE, 0x91, 0xCC, 0x94, 0xCD, 0x85, 0x08, 0xCE, + 0x91, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85, 0x08, + // Bytes 1180 - 11bf + 0xCE, 0x91, 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, + 0x08, 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x81, 0xCD, + 0x85, 0x08, 0xCE, 0x91, 0xCC, 0x94, 0xCC, 0x81, + 0xCD, 0x85, 0x08, 0xCE, 0x91, 0xCC, 0x93, 0xCD, + 0x82, 0xCD, 0x85, 0x08, 0xCE, 0x91, 0xCC, 0x94, + 0xCD, 0x82, 0xCD, 0x85, 0x06, 0xCE, 0xB7, 0xCC, + 0x93, 0xCD, 0x85, 0x06, 0xCE, 0xB7, 0xCC, 0x94, + 0xCD, 0x85, 0x08, 0xCE, 0xB7, 0xCC, 0x93, 0xCC, + // Bytes 11c0 - 11ff + 0x80, 0xCD, 0x85, 0x08, 0xCE, 0xB7, 0xCC, 0x94, + 0xCC, 0x80, 0xCD, 0x85, 0x08, 0xCE, 0xB7, 0xCC, + 0x93, 0xCC, 0x81, 0xCD, 0x85, 0x08, 0xCE, 0xB7, + 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85, 0x08, 0xCE, + 0xB7, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85, 0x08, + 0xCE, 0xB7, 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, + 0x06, 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x85, 0x06, + 0xCE, 0x97, 0xCC, 0x94, 0xCD, 0x85, 0x08, 0xCE, + // Bytes 1200 - 123f + 0x97, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85, 0x08, + 0xCE, 0x97, 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, + 0x08, 0xCE, 0x97, 0xCC, 0x93, 0xCC, 0x81, 0xCD, + 0x85, 0x08, 0xCE, 0x97, 0xCC, 0x94, 0xCC, 0x81, + 0xCD, 0x85, 0x08, 0xCE, 0x97, 0xCC, 0x93, 0xCD, + 0x82, 0xCD, 0x85, 0x08, 0xCE, 0x97, 0xCC, 0x94, + 0xCD, 0x82, 0xCD, 0x85, 0x06, 0xCF, 0x89, 0xCC, + 0x93, 0xCD, 0x85, 0x06, 0xCF, 0x89, 0xCC, 0x94, + // Bytes 1240 - 127f + 0xCD, 0x85, 0x08, 0xCF, 0x89, 0xCC, 0x93, 0xCC, + 0x80, 0xCD, 0x85, 0x08, 0xCF, 0x89, 0xCC, 0x94, + 0xCC, 0x80, 0xCD, 0x85, 0x08, 0xCF, 0x89, 0xCC, + 0x93, 0xCC, 0x81, 0xCD, 0x85, 0x08, 0xCF, 0x89, + 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85, 0x08, 0xCF, + 0x89, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85, 0x08, + 0xCF, 0x89, 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, + 0x06, 0xCE, 0xA9, 0xCC, 0x93, 0xCD, 0x85, 0x06, + // Bytes 1280 - 12bf + 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x85, 0x08, 0xCE, + 0xA9, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85, 0x08, + 0xCE, 0xA9, 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, + 0x08, 0xCE, 0xA9, 0xCC, 0x93, 0xCC, 0x81, 0xCD, + 0x85, 0x08, 0xCE, 0xA9, 0xCC, 0x94, 0xCC, 0x81, + 0xCD, 0x85, 0x08, 0xCE, 0xA9, 0xCC, 0x93, 0xCD, + 0x82, 0xCD, 0x85, 0x08, 0xCE, 0xA9, 0xCC, 0x94, + 0xCD, 0x82, 0xCD, 0x85, 0x04, 0xCE, 0xB1, 0xCC, + // Bytes 12c0 - 12ff + 0x86, 0x04, 0xCE, 0xB1, 0xCC, 0x84, 0x06, 0xCE, + 0xB1, 0xCC, 0x80, 0xCD, 0x85, 0x04, 0xCE, 0xB1, + 0xCD, 0x85, 0x06, 0xCE, 0xB1, 0xCC, 0x81, 0xCD, + 0x85, 0x04, 0xCE, 0xB1, 0xCD, 0x82, 0x06, 0xCE, + 0xB1, 0xCD, 0x82, 0xCD, 0x85, 0x04, 0xCE, 0x91, + 0xCC, 0x86, 0x04, 0xCE, 0x91, 0xCC, 0x84, 0x04, + 0xCE, 0x91, 0xCC, 0x80, 0x04, 0xCE, 0x91, 0xCD, + 0x85, 0x03, 0x20, 0xCC, 0x93, 0x02, 0xCE, 0xB9, + // Bytes 1300 - 133f + 0x03, 0x20, 0xCD, 0x82, 0x04, 0xC2, 0xA8, 0xCD, + 0x82, 0x05, 0x20, 0xCC, 0x88, 0xCD, 0x82, 0x06, + 0xCE, 0xB7, 0xCC, 0x80, 0xCD, 0x85, 0x04, 0xCE, + 0xB7, 0xCD, 0x85, 0x06, 0xCE, 0xB7, 0xCC, 0x81, + 0xCD, 0x85, 0x04, 0xCE, 0xB7, 0xCD, 0x82, 0x06, + 0xCE, 0xB7, 0xCD, 0x82, 0xCD, 0x85, 0x04, 0xCE, + 0x95, 0xCC, 0x80, 0x04, 0xCE, 0x97, 0xCC, 0x80, + 0x04, 0xCE, 0x97, 0xCD, 0x85, 0x05, 0xE1, 0xBE, + // Bytes 1340 - 137f + 0xBF, 0xCC, 0x80, 0x05, 0x20, 0xCC, 0x93, 0xCC, + 0x80, 0x05, 0xE1, 0xBE, 0xBF, 0xCC, 0x81, 0x05, + 0x20, 0xCC, 0x93, 0xCC, 0x81, 0x05, 0xE1, 0xBE, + 0xBF, 0xCD, 0x82, 0x05, 0x20, 0xCC, 0x93, 0xCD, + 0x82, 0x04, 0xCE, 0xB9, 0xCC, 0x86, 0x04, 0xCE, + 0xB9, 0xCC, 0x84, 0x06, 0xCE, 0xB9, 0xCC, 0x88, + 0xCC, 0x80, 0x04, 0xCE, 0xB9, 0xCD, 0x82, 0x06, + 0xCE, 0xB9, 0xCC, 0x88, 0xCD, 0x82, 0x04, 0xCE, + // Bytes 1380 - 13bf + 0x99, 0xCC, 0x86, 0x04, 0xCE, 0x99, 0xCC, 0x84, + 0x04, 0xCE, 0x99, 0xCC, 0x80, 0x05, 0xE1, 0xBF, + 0xBE, 0xCC, 0x80, 0x05, 0x20, 0xCC, 0x94, 0xCC, + 0x80, 0x05, 0xE1, 0xBF, 0xBE, 0xCC, 0x81, 0x05, + 0x20, 0xCC, 0x94, 0xCC, 0x81, 0x05, 0xE1, 0xBF, + 0xBE, 0xCD, 0x82, 0x05, 0x20, 0xCC, 0x94, 0xCD, + 0x82, 0x04, 0xCF, 0x85, 0xCC, 0x86, 0x04, 0xCF, + 0x85, 0xCC, 0x84, 0x06, 0xCF, 0x85, 0xCC, 0x88, + // Bytes 13c0 - 13ff + 0xCC, 0x80, 0x04, 0xCF, 0x81, 0xCC, 0x93, 0x04, + 0xCF, 0x81, 0xCC, 0x94, 0x04, 0xCF, 0x85, 0xCD, + 0x82, 0x06, 0xCF, 0x85, 0xCC, 0x88, 0xCD, 0x82, + 0x04, 0xCE, 0xA5, 0xCC, 0x86, 0x04, 0xCE, 0xA5, + 0xCC, 0x84, 0x04, 0xCE, 0xA5, 0xCC, 0x80, 0x04, + 0xCE, 0xA1, 0xCC, 0x94, 0x04, 0xC2, 0xA8, 0xCC, + 0x80, 0x05, 0x20, 0xCC, 0x88, 0xCC, 0x80, 0x01, + 0x60, 0x06, 0xCF, 0x89, 0xCC, 0x80, 0xCD, 0x85, + // Bytes 1400 - 143f + 0x04, 0xCF, 0x89, 0xCD, 0x85, 0x06, 0xCF, 0x89, + 0xCC, 0x81, 0xCD, 0x85, 0x04, 0xCF, 0x89, 0xCD, + 0x82, 0x06, 0xCF, 0x89, 0xCD, 0x82, 0xCD, 0x85, + 0x04, 0xCE, 0x9F, 0xCC, 0x80, 0x04, 0xCE, 0xA9, + 0xCC, 0x80, 0x04, 0xCE, 0xA9, 0xCD, 0x85, 0x02, + 0xC2, 0xB4, 0x03, 0x20, 0xCC, 0x94, 0x03, 0xE2, + 0x80, 0x82, 0x03, 0xE2, 0x80, 0x83, 0x03, 0xE2, + 0x80, 0x90, 0x03, 0x20, 0xCC, 0xB3, 0x01, 0x2E, + // Bytes 1440 - 147f + 0x02, 0x2E, 0x2E, 0x03, 0x2E, 0x2E, 0x2E, 0x06, + 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0x09, 0xE2, + 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, + 0x06, 0xE2, 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0x09, + 0xE2, 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0xE2, 0x80, + 0xB5, 0x02, 0x21, 0x21, 0x03, 0x20, 0xCC, 0x85, + 0x02, 0x3F, 0x3F, 0x02, 0x3F, 0x21, 0x02, 0x21, + 0x3F, 0x0C, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, + // Bytes 1480 - 14bf + 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0x01, 0x30, + 0x01, 0x34, 0x01, 0x35, 0x01, 0x36, 0x01, 0x37, + 0x01, 0x38, 0x01, 0x39, 0x01, 0x2B, 0x03, 0xE2, + 0x88, 0x92, 0x01, 0x3D, 0x01, 0x28, 0x01, 0x29, + 0x01, 0x6E, 0x02, 0x52, 0x73, 0x03, 0x61, 0x2F, + 0x63, 0x03, 0x61, 0x2F, 0x73, 0x01, 0x43, 0x03, + 0xC2, 0xB0, 0x43, 0x03, 0x63, 0x2F, 0x6F, 0x03, + 0x63, 0x2F, 0x75, 0x02, 0xC6, 0x90, 0x03, 0xC2, + // Bytes 14c0 - 14ff + 0xB0, 0x46, 0x02, 0xC4, 0xA7, 0x02, 0x4E, 0x6F, + 0x01, 0x51, 0x02, 0x53, 0x4D, 0x03, 0x54, 0x45, + 0x4C, 0x02, 0x54, 0x4D, 0x01, 0x5A, 0x02, 0xCE, + 0xA9, 0x01, 0x46, 0x02, 0xD7, 0x90, 0x02, 0xD7, + 0x91, 0x02, 0xD7, 0x92, 0x02, 0xD7, 0x93, 0x03, + 0x46, 0x41, 0x58, 0x02, 0xCE, 0x93, 0x02, 0xCE, + 0xA0, 0x03, 0xE2, 0x88, 0x91, 0x05, 0x31, 0xE2, + 0x81, 0x84, 0x37, 0x05, 0x31, 0xE2, 0x81, 0x84, + // Bytes 1500 - 153f + 0x39, 0x06, 0x31, 0xE2, 0x81, 0x84, 0x31, 0x30, + 0x05, 0x31, 0xE2, 0x81, 0x84, 0x33, 0x05, 0x32, + 0xE2, 0x81, 0x84, 0x33, 0x05, 0x31, 0xE2, 0x81, + 0x84, 0x35, 0x05, 0x32, 0xE2, 0x81, 0x84, 0x35, + 0x05, 0x33, 0xE2, 0x81, 0x84, 0x35, 0x05, 0x34, + 0xE2, 0x81, 0x84, 0x35, 0x05, 0x31, 0xE2, 0x81, + 0x84, 0x36, 0x05, 0x35, 0xE2, 0x81, 0x84, 0x36, + 0x05, 0x31, 0xE2, 0x81, 0x84, 0x38, 0x05, 0x33, + // Bytes 1540 - 157f + 0xE2, 0x81, 0x84, 0x38, 0x05, 0x35, 0xE2, 0x81, + 0x84, 0x38, 0x05, 0x37, 0xE2, 0x81, 0x84, 0x38, + 0x04, 0x31, 0xE2, 0x81, 0x84, 0x02, 0x49, 0x49, + 0x03, 0x49, 0x49, 0x49, 0x02, 0x49, 0x56, 0x01, + 0x56, 0x02, 0x56, 0x49, 0x03, 0x56, 0x49, 0x49, + 0x04, 0x56, 0x49, 0x49, 0x49, 0x02, 0x49, 0x58, + 0x01, 0x58, 0x02, 0x58, 0x49, 0x03, 0x58, 0x49, + 0x49, 0x02, 0x69, 0x69, 0x03, 0x69, 0x69, 0x69, + // Bytes 1580 - 15bf + 0x02, 0x69, 0x76, 0x02, 0x76, 0x69, 0x03, 0x76, + 0x69, 0x69, 0x04, 0x76, 0x69, 0x69, 0x69, 0x02, + 0x69, 0x78, 0x02, 0x78, 0x69, 0x03, 0x78, 0x69, + 0x69, 0x05, 0x30, 0xE2, 0x81, 0x84, 0x33, 0x05, + 0xE2, 0x86, 0x90, 0xCC, 0xB8, 0x05, 0xE2, 0x86, + 0x92, 0xCC, 0xB8, 0x05, 0xE2, 0x86, 0x94, 0xCC, + 0xB8, 0x05, 0xE2, 0x87, 0x90, 0xCC, 0xB8, 0x05, + 0xE2, 0x87, 0x94, 0xCC, 0xB8, 0x05, 0xE2, 0x87, + // Bytes 15c0 - 15ff + 0x92, 0xCC, 0xB8, 0x05, 0xE2, 0x88, 0x83, 0xCC, + 0xB8, 0x05, 0xE2, 0x88, 0x88, 0xCC, 0xB8, 0x05, + 0xE2, 0x88, 0x8B, 0xCC, 0xB8, 0x05, 0xE2, 0x88, + 0xA3, 0xCC, 0xB8, 0x05, 0xE2, 0x88, 0xA5, 0xCC, + 0xB8, 0x06, 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, + 0x09, 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2, + 0x88, 0xAB, 0x06, 0xE2, 0x88, 0xAE, 0xE2, 0x88, + 0xAE, 0x09, 0xE2, 0x88, 0xAE, 0xE2, 0x88, 0xAE, + // Bytes 1600 - 163f + 0xE2, 0x88, 0xAE, 0x05, 0xE2, 0x88, 0xBC, 0xCC, + 0xB8, 0x05, 0xE2, 0x89, 0x83, 0xCC, 0xB8, 0x05, + 0xE2, 0x89, 0x85, 0xCC, 0xB8, 0x05, 0xE2, 0x89, + 0x88, 0xCC, 0xB8, 0x03, 0x3D, 0xCC, 0xB8, 0x05, + 0xE2, 0x89, 0xA1, 0xCC, 0xB8, 0x05, 0xE2, 0x89, + 0x8D, 0xCC, 0xB8, 0x03, 0x3C, 0xCC, 0xB8, 0x03, + 0x3E, 0xCC, 0xB8, 0x05, 0xE2, 0x89, 0xA4, 0xCC, + 0xB8, 0x05, 0xE2, 0x89, 0xA5, 0xCC, 0xB8, 0x05, + // Bytes 1640 - 167f + 0xE2, 0x89, 0xB2, 0xCC, 0xB8, 0x05, 0xE2, 0x89, + 0xB3, 0xCC, 0xB8, 0x05, 0xE2, 0x89, 0xB6, 0xCC, + 0xB8, 0x05, 0xE2, 0x89, 0xB7, 0xCC, 0xB8, 0x05, + 0xE2, 0x89, 0xBA, 0xCC, 0xB8, 0x05, 0xE2, 0x89, + 0xBB, 0xCC, 0xB8, 0x05, 0xE2, 0x8A, 0x82, 0xCC, + 0xB8, 0x05, 0xE2, 0x8A, 0x83, 0xCC, 0xB8, 0x05, + 0xE2, 0x8A, 0x86, 0xCC, 0xB8, 0x05, 0xE2, 0x8A, + 0x87, 0xCC, 0xB8, 0x05, 0xE2, 0x8A, 0xA2, 0xCC, + // Bytes 1680 - 16bf + 0xB8, 0x05, 0xE2, 0x8A, 0xA8, 0xCC, 0xB8, 0x05, + 0xE2, 0x8A, 0xA9, 0xCC, 0xB8, 0x05, 0xE2, 0x8A, + 0xAB, 0xCC, 0xB8, 0x05, 0xE2, 0x89, 0xBC, 0xCC, + 0xB8, 0x05, 0xE2, 0x89, 0xBD, 0xCC, 0xB8, 0x05, + 0xE2, 0x8A, 0x91, 0xCC, 0xB8, 0x05, 0xE2, 0x8A, + 0x92, 0xCC, 0xB8, 0x05, 0xE2, 0x8A, 0xB2, 0xCC, + 0xB8, 0x05, 0xE2, 0x8A, 0xB3, 0xCC, 0xB8, 0x05, + 0xE2, 0x8A, 0xB4, 0xCC, 0xB8, 0x05, 0xE2, 0x8A, + // Bytes 16c0 - 16ff + 0xB5, 0xCC, 0xB8, 0x03, 0xE3, 0x80, 0x88, 0x03, + 0xE3, 0x80, 0x89, 0x02, 0x31, 0x30, 0x02, 0x31, + 0x31, 0x02, 0x31, 0x32, 0x02, 0x31, 0x33, 0x02, + 0x31, 0x34, 0x02, 0x31, 0x35, 0x02, 0x31, 0x36, + 0x02, 0x31, 0x37, 0x02, 0x31, 0x38, 0x02, 0x31, + 0x39, 0x02, 0x32, 0x30, 0x03, 0x28, 0x31, 0x29, + 0x03, 0x28, 0x32, 0x29, 0x03, 0x28, 0x33, 0x29, + 0x03, 0x28, 0x34, 0x29, 0x03, 0x28, 0x35, 0x29, + // Bytes 1700 - 173f + 0x03, 0x28, 0x36, 0x29, 0x03, 0x28, 0x37, 0x29, + 0x03, 0x28, 0x38, 0x29, 0x03, 0x28, 0x39, 0x29, + 0x04, 0x28, 0x31, 0x30, 0x29, 0x04, 0x28, 0x31, + 0x31, 0x29, 0x04, 0x28, 0x31, 0x32, 0x29, 0x04, + 0x28, 0x31, 0x33, 0x29, 0x04, 0x28, 0x31, 0x34, + 0x29, 0x04, 0x28, 0x31, 0x35, 0x29, 0x04, 0x28, + 0x31, 0x36, 0x29, 0x04, 0x28, 0x31, 0x37, 0x29, + 0x04, 0x28, 0x31, 0x38, 0x29, 0x04, 0x28, 0x31, + // Bytes 1740 - 177f + 0x39, 0x29, 0x04, 0x28, 0x32, 0x30, 0x29, 0x02, + 0x31, 0x2E, 0x02, 0x32, 0x2E, 0x02, 0x33, 0x2E, + 0x02, 0x34, 0x2E, 0x02, 0x35, 0x2E, 0x02, 0x36, + 0x2E, 0x02, 0x37, 0x2E, 0x02, 0x38, 0x2E, 0x02, + 0x39, 0x2E, 0x03, 0x31, 0x30, 0x2E, 0x03, 0x31, + 0x31, 0x2E, 0x03, 0x31, 0x32, 0x2E, 0x03, 0x31, + 0x33, 0x2E, 0x03, 0x31, 0x34, 0x2E, 0x03, 0x31, + 0x35, 0x2E, 0x03, 0x31, 0x36, 0x2E, 0x03, 0x31, + // Bytes 1780 - 17bf + 0x37, 0x2E, 0x03, 0x31, 0x38, 0x2E, 0x03, 0x31, + 0x39, 0x2E, 0x03, 0x32, 0x30, 0x2E, 0x03, 0x28, + 0x61, 0x29, 0x03, 0x28, 0x62, 0x29, 0x03, 0x28, + 0x63, 0x29, 0x03, 0x28, 0x64, 0x29, 0x03, 0x28, + 0x65, 0x29, 0x03, 0x28, 0x66, 0x29, 0x03, 0x28, + 0x67, 0x29, 0x03, 0x28, 0x68, 0x29, 0x03, 0x28, + 0x69, 0x29, 0x03, 0x28, 0x6A, 0x29, 0x03, 0x28, + 0x6B, 0x29, 0x03, 0x28, 0x6C, 0x29, 0x03, 0x28, + // Bytes 17c0 - 17ff + 0x6D, 0x29, 0x03, 0x28, 0x6E, 0x29, 0x03, 0x28, + 0x6F, 0x29, 0x03, 0x28, 0x70, 0x29, 0x03, 0x28, + 0x71, 0x29, 0x03, 0x28, 0x72, 0x29, 0x03, 0x28, + 0x73, 0x29, 0x03, 0x28, 0x74, 0x29, 0x03, 0x28, + 0x75, 0x29, 0x03, 0x28, 0x76, 0x29, 0x03, 0x28, + 0x77, 0x29, 0x03, 0x28, 0x78, 0x29, 0x03, 0x28, + 0x79, 0x29, 0x03, 0x28, 0x7A, 0x29, 0x01, 0x53, + 0x01, 0x59, 0x01, 0x71, 0x0C, 0xE2, 0x88, 0xAB, + // Bytes 1800 - 183f + 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2, 0x88, + 0xAB, 0x03, 0x3A, 0x3A, 0x3D, 0x02, 0x3D, 0x3D, + 0x03, 0x3D, 0x3D, 0x3D, 0x05, 0xE2, 0xAB, 0x9D, + 0xCC, 0xB8, 0x03, 0xE2, 0xB5, 0xA1, 0x03, 0xE6, + 0xAF, 0x8D, 0x03, 0xE9, 0xBE, 0x9F, 0x03, 0xE4, + 0xB8, 0x80, 0x03, 0xE4, 0xB8, 0xA8, 0x03, 0xE4, + 0xB8, 0xB6, 0x03, 0xE4, 0xB8, 0xBF, 0x03, 0xE4, + 0xB9, 0x99, 0x03, 0xE4, 0xBA, 0x85, 0x03, 0xE4, + // Bytes 1840 - 187f + 0xBA, 0x8C, 0x03, 0xE4, 0xBA, 0xA0, 0x03, 0xE4, + 0xBA, 0xBA, 0x03, 0xE5, 0x84, 0xBF, 0x03, 0xE5, + 0x85, 0xA5, 0x03, 0xE5, 0x85, 0xAB, 0x03, 0xE5, + 0x86, 0x82, 0x03, 0xE5, 0x86, 0x96, 0x03, 0xE5, + 0x86, 0xAB, 0x03, 0xE5, 0x87, 0xA0, 0x03, 0xE5, + 0x87, 0xB5, 0x03, 0xE5, 0x88, 0x80, 0x03, 0xE5, + 0x8A, 0x9B, 0x03, 0xE5, 0x8B, 0xB9, 0x03, 0xE5, + 0x8C, 0x95, 0x03, 0xE5, 0x8C, 0x9A, 0x03, 0xE5, + // Bytes 1880 - 18bf + 0x8C, 0xB8, 0x03, 0xE5, 0x8D, 0x81, 0x03, 0xE5, + 0x8D, 0x9C, 0x03, 0xE5, 0x8D, 0xA9, 0x03, 0xE5, + 0x8E, 0x82, 0x03, 0xE5, 0x8E, 0xB6, 0x03, 0xE5, + 0x8F, 0x88, 0x03, 0xE5, 0x8F, 0xA3, 0x03, 0xE5, + 0x9B, 0x97, 0x03, 0xE5, 0x9C, 0x9F, 0x03, 0xE5, + 0xA3, 0xAB, 0x03, 0xE5, 0xA4, 0x82, 0x03, 0xE5, + 0xA4, 0x8A, 0x03, 0xE5, 0xA4, 0x95, 0x03, 0xE5, + 0xA4, 0xA7, 0x03, 0xE5, 0xA5, 0xB3, 0x03, 0xE5, + // Bytes 18c0 - 18ff + 0xAD, 0x90, 0x03, 0xE5, 0xAE, 0x80, 0x03, 0xE5, + 0xAF, 0xB8, 0x03, 0xE5, 0xB0, 0x8F, 0x03, 0xE5, + 0xB0, 0xA2, 0x03, 0xE5, 0xB0, 0xB8, 0x03, 0xE5, + 0xB1, 0xAE, 0x03, 0xE5, 0xB1, 0xB1, 0x03, 0xE5, + 0xB7, 0x9B, 0x03, 0xE5, 0xB7, 0xA5, 0x03, 0xE5, + 0xB7, 0xB1, 0x03, 0xE5, 0xB7, 0xBE, 0x03, 0xE5, + 0xB9, 0xB2, 0x03, 0xE5, 0xB9, 0xBA, 0x03, 0xE5, + 0xB9, 0xBF, 0x03, 0xE5, 0xBB, 0xB4, 0x03, 0xE5, + // Bytes 1900 - 193f + 0xBB, 0xBE, 0x03, 0xE5, 0xBC, 0x8B, 0x03, 0xE5, + 0xBC, 0x93, 0x03, 0xE5, 0xBD, 0x90, 0x03, 0xE5, + 0xBD, 0xA1, 0x03, 0xE5, 0xBD, 0xB3, 0x03, 0xE5, + 0xBF, 0x83, 0x03, 0xE6, 0x88, 0x88, 0x03, 0xE6, + 0x88, 0xB6, 0x03, 0xE6, 0x89, 0x8B, 0x03, 0xE6, + 0x94, 0xAF, 0x03, 0xE6, 0x94, 0xB4, 0x03, 0xE6, + 0x96, 0x87, 0x03, 0xE6, 0x96, 0x97, 0x03, 0xE6, + 0x96, 0xA4, 0x03, 0xE6, 0x96, 0xB9, 0x03, 0xE6, + // Bytes 1940 - 197f + 0x97, 0xA0, 0x03, 0xE6, 0x97, 0xA5, 0x03, 0xE6, + 0x9B, 0xB0, 0x03, 0xE6, 0x9C, 0x88, 0x03, 0xE6, + 0x9C, 0xA8, 0x03, 0xE6, 0xAC, 0xA0, 0x03, 0xE6, + 0xAD, 0xA2, 0x03, 0xE6, 0xAD, 0xB9, 0x03, 0xE6, + 0xAE, 0xB3, 0x03, 0xE6, 0xAF, 0x8B, 0x03, 0xE6, + 0xAF, 0x94, 0x03, 0xE6, 0xAF, 0x9B, 0x03, 0xE6, + 0xB0, 0x8F, 0x03, 0xE6, 0xB0, 0x94, 0x03, 0xE6, + 0xB0, 0xB4, 0x03, 0xE7, 0x81, 0xAB, 0x03, 0xE7, + // Bytes 1980 - 19bf + 0x88, 0xAA, 0x03, 0xE7, 0x88, 0xB6, 0x03, 0xE7, + 0x88, 0xBB, 0x03, 0xE7, 0x88, 0xBF, 0x03, 0xE7, + 0x89, 0x87, 0x03, 0xE7, 0x89, 0x99, 0x03, 0xE7, + 0x89, 0x9B, 0x03, 0xE7, 0x8A, 0xAC, 0x03, 0xE7, + 0x8E, 0x84, 0x03, 0xE7, 0x8E, 0x89, 0x03, 0xE7, + 0x93, 0x9C, 0x03, 0xE7, 0x93, 0xA6, 0x03, 0xE7, + 0x94, 0x98, 0x03, 0xE7, 0x94, 0x9F, 0x03, 0xE7, + 0x94, 0xA8, 0x03, 0xE7, 0x94, 0xB0, 0x03, 0xE7, + // Bytes 19c0 - 19ff + 0x96, 0x8B, 0x03, 0xE7, 0x96, 0x92, 0x03, 0xE7, + 0x99, 0xB6, 0x03, 0xE7, 0x99, 0xBD, 0x03, 0xE7, + 0x9A, 0xAE, 0x03, 0xE7, 0x9A, 0xBF, 0x03, 0xE7, + 0x9B, 0xAE, 0x03, 0xE7, 0x9F, 0x9B, 0x03, 0xE7, + 0x9F, 0xA2, 0x03, 0xE7, 0x9F, 0xB3, 0x03, 0xE7, + 0xA4, 0xBA, 0x03, 0xE7, 0xA6, 0xB8, 0x03, 0xE7, + 0xA6, 0xBE, 0x03, 0xE7, 0xA9, 0xB4, 0x03, 0xE7, + 0xAB, 0x8B, 0x03, 0xE7, 0xAB, 0xB9, 0x03, 0xE7, + // Bytes 1a00 - 1a3f + 0xB1, 0xB3, 0x03, 0xE7, 0xB3, 0xB8, 0x03, 0xE7, + 0xBC, 0xB6, 0x03, 0xE7, 0xBD, 0x91, 0x03, 0xE7, + 0xBE, 0x8A, 0x03, 0xE7, 0xBE, 0xBD, 0x03, 0xE8, + 0x80, 0x81, 0x03, 0xE8, 0x80, 0x8C, 0x03, 0xE8, + 0x80, 0x92, 0x03, 0xE8, 0x80, 0xB3, 0x03, 0xE8, + 0x81, 0xBF, 0x03, 0xE8, 0x82, 0x89, 0x03, 0xE8, + 0x87, 0xA3, 0x03, 0xE8, 0x87, 0xAA, 0x03, 0xE8, + 0x87, 0xB3, 0x03, 0xE8, 0x87, 0xBC, 0x03, 0xE8, + // Bytes 1a40 - 1a7f + 0x88, 0x8C, 0x03, 0xE8, 0x88, 0x9B, 0x03, 0xE8, + 0x88, 0x9F, 0x03, 0xE8, 0x89, 0xAE, 0x03, 0xE8, + 0x89, 0xB2, 0x03, 0xE8, 0x89, 0xB8, 0x03, 0xE8, + 0x99, 0x8D, 0x03, 0xE8, 0x99, 0xAB, 0x03, 0xE8, + 0xA1, 0x80, 0x03, 0xE8, 0xA1, 0x8C, 0x03, 0xE8, + 0xA1, 0xA3, 0x03, 0xE8, 0xA5, 0xBE, 0x03, 0xE8, + 0xA6, 0x8B, 0x03, 0xE8, 0xA7, 0x92, 0x03, 0xE8, + 0xA8, 0x80, 0x03, 0xE8, 0xB0, 0xB7, 0x03, 0xE8, + // Bytes 1a80 - 1abf + 0xB1, 0x86, 0x03, 0xE8, 0xB1, 0x95, 0x03, 0xE8, + 0xB1, 0xB8, 0x03, 0xE8, 0xB2, 0x9D, 0x03, 0xE8, + 0xB5, 0xA4, 0x03, 0xE8, 0xB5, 0xB0, 0x03, 0xE8, + 0xB6, 0xB3, 0x03, 0xE8, 0xBA, 0xAB, 0x03, 0xE8, + 0xBB, 0x8A, 0x03, 0xE8, 0xBE, 0x9B, 0x03, 0xE8, + 0xBE, 0xB0, 0x03, 0xE8, 0xBE, 0xB5, 0x03, 0xE9, + 0x82, 0x91, 0x03, 0xE9, 0x85, 0x89, 0x03, 0xE9, + 0x87, 0x86, 0x03, 0xE9, 0x87, 0x8C, 0x03, 0xE9, + // Bytes 1ac0 - 1aff + 0x87, 0x91, 0x03, 0xE9, 0x95, 0xB7, 0x03, 0xE9, + 0x96, 0x80, 0x03, 0xE9, 0x98, 0x9C, 0x03, 0xE9, + 0x9A, 0xB6, 0x03, 0xE9, 0x9A, 0xB9, 0x03, 0xE9, + 0x9B, 0xA8, 0x03, 0xE9, 0x9D, 0x91, 0x03, 0xE9, + 0x9D, 0x9E, 0x03, 0xE9, 0x9D, 0xA2, 0x03, 0xE9, + 0x9D, 0xA9, 0x03, 0xE9, 0x9F, 0x8B, 0x03, 0xE9, + 0x9F, 0xAD, 0x03, 0xE9, 0x9F, 0xB3, 0x03, 0xE9, + 0xA0, 0x81, 0x03, 0xE9, 0xA2, 0xA8, 0x03, 0xE9, + // Bytes 1b00 - 1b3f + 0xA3, 0x9B, 0x03, 0xE9, 0xA3, 0x9F, 0x03, 0xE9, + 0xA6, 0x96, 0x03, 0xE9, 0xA6, 0x99, 0x03, 0xE9, + 0xA6, 0xAC, 0x03, 0xE9, 0xAA, 0xA8, 0x03, 0xE9, + 0xAB, 0x98, 0x03, 0xE9, 0xAB, 0x9F, 0x03, 0xE9, + 0xAC, 0xA5, 0x03, 0xE9, 0xAC, 0xAF, 0x03, 0xE9, + 0xAC, 0xB2, 0x03, 0xE9, 0xAC, 0xBC, 0x03, 0xE9, + 0xAD, 0x9A, 0x03, 0xE9, 0xB3, 0xA5, 0x03, 0xE9, + 0xB9, 0xB5, 0x03, 0xE9, 0xB9, 0xBF, 0x03, 0xE9, + // Bytes 1b40 - 1b7f + 0xBA, 0xA5, 0x03, 0xE9, 0xBA, 0xBB, 0x03, 0xE9, + 0xBB, 0x83, 0x03, 0xE9, 0xBB, 0x8D, 0x03, 0xE9, + 0xBB, 0x91, 0x03, 0xE9, 0xBB, 0xB9, 0x03, 0xE9, + 0xBB, 0xBD, 0x03, 0xE9, 0xBC, 0x8E, 0x03, 0xE9, + 0xBC, 0x93, 0x03, 0xE9, 0xBC, 0xA0, 0x03, 0xE9, + 0xBC, 0xBB, 0x03, 0xE9, 0xBD, 0x8A, 0x03, 0xE9, + 0xBD, 0x92, 0x03, 0xE9, 0xBE, 0x8D, 0x03, 0xE9, + 0xBE, 0x9C, 0x03, 0xE9, 0xBE, 0xA0, 0x03, 0xE3, + // Bytes 1b80 - 1bbf + 0x80, 0x92, 0x03, 0xE5, 0x8D, 0x84, 0x03, 0xE5, + 0x8D, 0x85, 0x06, 0xE3, 0x81, 0x8B, 0xE3, 0x82, + 0x99, 0x06, 0xE3, 0x81, 0x8D, 0xE3, 0x82, 0x99, + 0x06, 0xE3, 0x81, 0x8F, 0xE3, 0x82, 0x99, 0x06, + 0xE3, 0x81, 0x91, 0xE3, 0x82, 0x99, 0x06, 0xE3, + 0x81, 0x93, 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x81, + 0x95, 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x81, 0x97, + 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x81, 0x99, 0xE3, + // Bytes 1bc0 - 1bff + 0x82, 0x99, 0x06, 0xE3, 0x81, 0x9B, 0xE3, 0x82, + 0x99, 0x06, 0xE3, 0x81, 0x9D, 0xE3, 0x82, 0x99, + 0x06, 0xE3, 0x81, 0x9F, 0xE3, 0x82, 0x99, 0x06, + 0xE3, 0x81, 0xA1, 0xE3, 0x82, 0x99, 0x06, 0xE3, + 0x81, 0xA4, 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x81, + 0xA6, 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x81, 0xA8, + 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x81, 0xAF, 0xE3, + 0x82, 0x99, 0x06, 0xE3, 0x81, 0xAF, 0xE3, 0x82, + // Bytes 1c00 - 1c3f + 0x9A, 0x06, 0xE3, 0x81, 0xB2, 0xE3, 0x82, 0x99, + 0x06, 0xE3, 0x81, 0xB2, 0xE3, 0x82, 0x9A, 0x06, + 0xE3, 0x81, 0xB5, 0xE3, 0x82, 0x99, 0x06, 0xE3, + 0x81, 0xB5, 0xE3, 0x82, 0x9A, 0x06, 0xE3, 0x81, + 0xB8, 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x81, 0xB8, + 0xE3, 0x82, 0x9A, 0x06, 0xE3, 0x81, 0xBB, 0xE3, + 0x82, 0x99, 0x06, 0xE3, 0x81, 0xBB, 0xE3, 0x82, + 0x9A, 0x06, 0xE3, 0x81, 0x86, 0xE3, 0x82, 0x99, + // Bytes 1c40 - 1c7f + 0x04, 0x20, 0xE3, 0x82, 0x99, 0x04, 0x20, 0xE3, + 0x82, 0x9A, 0x06, 0xE3, 0x82, 0x9D, 0xE3, 0x82, + 0x99, 0x06, 0xE3, 0x82, 0x88, 0xE3, 0x82, 0x8A, + 0x06, 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0x06, + 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0x99, 0x06, 0xE3, + 0x82, 0xAF, 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x82, + 0xB1, 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x82, 0xB3, + 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x82, 0xB5, 0xE3, + // Bytes 1c80 - 1cbf + 0x82, 0x99, 0x06, 0xE3, 0x82, 0xB7, 0xE3, 0x82, + 0x99, 0x06, 0xE3, 0x82, 0xB9, 0xE3, 0x82, 0x99, + 0x06, 0xE3, 0x82, 0xBB, 0xE3, 0x82, 0x99, 0x06, + 0xE3, 0x82, 0xBD, 0xE3, 0x82, 0x99, 0x06, 0xE3, + 0x82, 0xBF, 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x83, + 0x81, 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x83, 0x84, + 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x83, 0x86, 0xE3, + 0x82, 0x99, 0x06, 0xE3, 0x83, 0x88, 0xE3, 0x82, + // Bytes 1cc0 - 1cff + 0x99, 0x06, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x99, + 0x06, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A, 0x06, + 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x99, 0x06, 0xE3, + 0x83, 0x92, 0xE3, 0x82, 0x9A, 0x06, 0xE3, 0x83, + 0x95, 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x83, 0x95, + 0xE3, 0x82, 0x9A, 0x06, 0xE3, 0x83, 0x98, 0xE3, + 0x82, 0x99, 0x06, 0xE3, 0x83, 0x98, 0xE3, 0x82, + 0x9A, 0x06, 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x99, + // Bytes 1d00 - 1d3f + 0x06, 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x9A, 0x06, + 0xE3, 0x82, 0xA6, 0xE3, 0x82, 0x99, 0x06, 0xE3, + 0x83, 0xAF, 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x83, + 0xB0, 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x83, 0xB1, + 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x83, 0xB2, 0xE3, + 0x82, 0x99, 0x06, 0xE3, 0x83, 0xBD, 0xE3, 0x82, + 0x99, 0x06, 0xE3, 0x82, 0xB3, 0xE3, 0x83, 0x88, + 0x03, 0xE1, 0x84, 0x80, 0x03, 0xE1, 0x84, 0x81, + // Bytes 1d40 - 1d7f + 0x03, 0xE1, 0x86, 0xAA, 0x03, 0xE1, 0x84, 0x82, + 0x03, 0xE1, 0x86, 0xAC, 0x03, 0xE1, 0x86, 0xAD, + 0x03, 0xE1, 0x84, 0x83, 0x03, 0xE1, 0x84, 0x84, + 0x03, 0xE1, 0x84, 0x85, 0x03, 0xE1, 0x86, 0xB0, + 0x03, 0xE1, 0x86, 0xB1, 0x03, 0xE1, 0x86, 0xB2, + 0x03, 0xE1, 0x86, 0xB3, 0x03, 0xE1, 0x86, 0xB4, + 0x03, 0xE1, 0x86, 0xB5, 0x03, 0xE1, 0x84, 0x9A, + 0x03, 0xE1, 0x84, 0x86, 0x03, 0xE1, 0x84, 0x87, + // Bytes 1d80 - 1dbf + 0x03, 0xE1, 0x84, 0x88, 0x03, 0xE1, 0x84, 0xA1, + 0x03, 0xE1, 0x84, 0x89, 0x03, 0xE1, 0x84, 0x8A, + 0x03, 0xE1, 0x84, 0x8B, 0x03, 0xE1, 0x84, 0x8C, + 0x03, 0xE1, 0x84, 0x8D, 0x03, 0xE1, 0x84, 0x8E, + 0x03, 0xE1, 0x84, 0x8F, 0x03, 0xE1, 0x84, 0x90, + 0x03, 0xE1, 0x84, 0x91, 0x03, 0xE1, 0x84, 0x92, + 0x03, 0xE1, 0x85, 0xA1, 0x03, 0xE1, 0x85, 0xA2, + 0x03, 0xE1, 0x85, 0xA3, 0x03, 0xE1, 0x85, 0xA4, + // Bytes 1dc0 - 1dff + 0x03, 0xE1, 0x85, 0xA5, 0x03, 0xE1, 0x85, 0xA6, + 0x03, 0xE1, 0x85, 0xA7, 0x03, 0xE1, 0x85, 0xA8, + 0x03, 0xE1, 0x85, 0xA9, 0x03, 0xE1, 0x85, 0xAA, + 0x03, 0xE1, 0x85, 0xAB, 0x03, 0xE1, 0x85, 0xAC, + 0x03, 0xE1, 0x85, 0xAD, 0x03, 0xE1, 0x85, 0xAE, + 0x03, 0xE1, 0x85, 0xAF, 0x03, 0xE1, 0x85, 0xB0, + 0x03, 0xE1, 0x85, 0xB1, 0x03, 0xE1, 0x85, 0xB2, + 0x03, 0xE1, 0x85, 0xB3, 0x03, 0xE1, 0x85, 0xB4, + // Bytes 1e00 - 1e3f + 0x03, 0xE1, 0x85, 0xB5, 0x03, 0xE1, 0x85, 0xA0, + 0x03, 0xE1, 0x84, 0x94, 0x03, 0xE1, 0x84, 0x95, + 0x03, 0xE1, 0x87, 0x87, 0x03, 0xE1, 0x87, 0x88, + 0x03, 0xE1, 0x87, 0x8C, 0x03, 0xE1, 0x87, 0x8E, + 0x03, 0xE1, 0x87, 0x93, 0x03, 0xE1, 0x87, 0x97, + 0x03, 0xE1, 0x87, 0x99, 0x03, 0xE1, 0x84, 0x9C, + 0x03, 0xE1, 0x87, 0x9D, 0x03, 0xE1, 0x87, 0x9F, + 0x03, 0xE1, 0x84, 0x9D, 0x03, 0xE1, 0x84, 0x9E, + // Bytes 1e40 - 1e7f + 0x03, 0xE1, 0x84, 0xA0, 0x03, 0xE1, 0x84, 0xA2, + 0x03, 0xE1, 0x84, 0xA3, 0x03, 0xE1, 0x84, 0xA7, + 0x03, 0xE1, 0x84, 0xA9, 0x03, 0xE1, 0x84, 0xAB, + 0x03, 0xE1, 0x84, 0xAC, 0x03, 0xE1, 0x84, 0xAD, + 0x03, 0xE1, 0x84, 0xAE, 0x03, 0xE1, 0x84, 0xAF, + 0x03, 0xE1, 0x84, 0xB2, 0x03, 0xE1, 0x84, 0xB6, + 0x03, 0xE1, 0x85, 0x80, 0x03, 0xE1, 0x85, 0x87, + 0x03, 0xE1, 0x85, 0x8C, 0x03, 0xE1, 0x87, 0xB1, + // Bytes 1e80 - 1ebf + 0x03, 0xE1, 0x87, 0xB2, 0x03, 0xE1, 0x85, 0x97, + 0x03, 0xE1, 0x85, 0x98, 0x03, 0xE1, 0x85, 0x99, + 0x03, 0xE1, 0x86, 0x84, 0x03, 0xE1, 0x86, 0x85, + 0x03, 0xE1, 0x86, 0x88, 0x03, 0xE1, 0x86, 0x91, + 0x03, 0xE1, 0x86, 0x92, 0x03, 0xE1, 0x86, 0x94, + 0x03, 0xE1, 0x86, 0x9E, 0x03, 0xE1, 0x86, 0xA1, + 0x03, 0xE4, 0xB8, 0x89, 0x03, 0xE5, 0x9B, 0x9B, + 0x03, 0xE4, 0xB8, 0x8A, 0x03, 0xE4, 0xB8, 0xAD, + // Bytes 1ec0 - 1eff + 0x03, 0xE4, 0xB8, 0x8B, 0x03, 0xE7, 0x94, 0xB2, + 0x03, 0xE4, 0xB8, 0x99, 0x03, 0xE4, 0xB8, 0x81, + 0x03, 0xE5, 0xA4, 0xA9, 0x03, 0xE5, 0x9C, 0xB0, + 0x05, 0x28, 0xE1, 0x84, 0x80, 0x29, 0x05, 0x28, + 0xE1, 0x84, 0x82, 0x29, 0x05, 0x28, 0xE1, 0x84, + 0x83, 0x29, 0x05, 0x28, 0xE1, 0x84, 0x85, 0x29, + 0x05, 0x28, 0xE1, 0x84, 0x86, 0x29, 0x05, 0x28, + 0xE1, 0x84, 0x87, 0x29, 0x05, 0x28, 0xE1, 0x84, + // Bytes 1f00 - 1f3f + 0x89, 0x29, 0x05, 0x28, 0xE1, 0x84, 0x8B, 0x29, + 0x05, 0x28, 0xE1, 0x84, 0x8C, 0x29, 0x05, 0x28, + 0xE1, 0x84, 0x8E, 0x29, 0x05, 0x28, 0xE1, 0x84, + 0x8F, 0x29, 0x05, 0x28, 0xE1, 0x84, 0x90, 0x29, + 0x05, 0x28, 0xE1, 0x84, 0x91, 0x29, 0x05, 0x28, + 0xE1, 0x84, 0x92, 0x29, 0x08, 0x28, 0xE1, 0x84, + 0x80, 0xE1, 0x85, 0xA1, 0x29, 0x08, 0x28, 0xE1, + 0x84, 0x82, 0xE1, 0x85, 0xA1, 0x29, 0x08, 0x28, + // Bytes 1f40 - 1f7f + 0xE1, 0x84, 0x83, 0xE1, 0x85, 0xA1, 0x29, 0x08, + 0x28, 0xE1, 0x84, 0x85, 0xE1, 0x85, 0xA1, 0x29, + 0x08, 0x28, 0xE1, 0x84, 0x86, 0xE1, 0x85, 0xA1, + 0x29, 0x08, 0x28, 0xE1, 0x84, 0x87, 0xE1, 0x85, + 0xA1, 0x29, 0x08, 0x28, 0xE1, 0x84, 0x89, 0xE1, + 0x85, 0xA1, 0x29, 0x08, 0x28, 0xE1, 0x84, 0x8B, + 0xE1, 0x85, 0xA1, 0x29, 0x08, 0x28, 0xE1, 0x84, + 0x8C, 0xE1, 0x85, 0xA1, 0x29, 0x08, 0x28, 0xE1, + // Bytes 1f80 - 1fbf + 0x84, 0x8E, 0xE1, 0x85, 0xA1, 0x29, 0x08, 0x28, + 0xE1, 0x84, 0x8F, 0xE1, 0x85, 0xA1, 0x29, 0x08, + 0x28, 0xE1, 0x84, 0x90, 0xE1, 0x85, 0xA1, 0x29, + 0x08, 0x28, 0xE1, 0x84, 0x91, 0xE1, 0x85, 0xA1, + 0x29, 0x08, 0x28, 0xE1, 0x84, 0x92, 0xE1, 0x85, + 0xA1, 0x29, 0x08, 0x28, 0xE1, 0x84, 0x8C, 0xE1, + 0x85, 0xAE, 0x29, 0x11, 0x28, 0xE1, 0x84, 0x8B, + 0xE1, 0x85, 0xA9, 0xE1, 0x84, 0x8C, 0xE1, 0x85, + // Bytes 1fc0 - 1fff + 0xA5, 0xE1, 0x86, 0xAB, 0x29, 0x0E, 0x28, 0xE1, + 0x84, 0x8B, 0xE1, 0x85, 0xA9, 0xE1, 0x84, 0x92, + 0xE1, 0x85, 0xAE, 0x29, 0x05, 0x28, 0xE4, 0xB8, + 0x80, 0x29, 0x05, 0x28, 0xE4, 0xBA, 0x8C, 0x29, + 0x05, 0x28, 0xE4, 0xB8, 0x89, 0x29, 0x05, 0x28, + 0xE5, 0x9B, 0x9B, 0x29, 0x05, 0x28, 0xE4, 0xBA, + 0x94, 0x29, 0x05, 0x28, 0xE5, 0x85, 0xAD, 0x29, + 0x05, 0x28, 0xE4, 0xB8, 0x83, 0x29, 0x05, 0x28, + // Bytes 2000 - 203f + 0xE5, 0x85, 0xAB, 0x29, 0x05, 0x28, 0xE4, 0xB9, + 0x9D, 0x29, 0x05, 0x28, 0xE5, 0x8D, 0x81, 0x29, + 0x05, 0x28, 0xE6, 0x9C, 0x88, 0x29, 0x05, 0x28, + 0xE7, 0x81, 0xAB, 0x29, 0x05, 0x28, 0xE6, 0xB0, + 0xB4, 0x29, 0x05, 0x28, 0xE6, 0x9C, 0xA8, 0x29, + 0x05, 0x28, 0xE9, 0x87, 0x91, 0x29, 0x05, 0x28, + 0xE5, 0x9C, 0x9F, 0x29, 0x05, 0x28, 0xE6, 0x97, + 0xA5, 0x29, 0x05, 0x28, 0xE6, 0xA0, 0xAA, 0x29, + // Bytes 2040 - 207f + 0x05, 0x28, 0xE6, 0x9C, 0x89, 0x29, 0x05, 0x28, + 0xE7, 0xA4, 0xBE, 0x29, 0x05, 0x28, 0xE5, 0x90, + 0x8D, 0x29, 0x05, 0x28, 0xE7, 0x89, 0xB9, 0x29, + 0x05, 0x28, 0xE8, 0xB2, 0xA1, 0x29, 0x05, 0x28, + 0xE7, 0xA5, 0x9D, 0x29, 0x05, 0x28, 0xE5, 0x8A, + 0xB4, 0x29, 0x05, 0x28, 0xE4, 0xBB, 0xA3, 0x29, + 0x05, 0x28, 0xE5, 0x91, 0xBC, 0x29, 0x05, 0x28, + 0xE5, 0xAD, 0xA6, 0x29, 0x05, 0x28, 0xE7, 0x9B, + // Bytes 2080 - 20bf + 0xA3, 0x29, 0x05, 0x28, 0xE4, 0xBC, 0x81, 0x29, + 0x05, 0x28, 0xE8, 0xB3, 0x87, 0x29, 0x05, 0x28, + 0xE5, 0x8D, 0x94, 0x29, 0x05, 0x28, 0xE7, 0xA5, + 0xAD, 0x29, 0x05, 0x28, 0xE4, 0xBC, 0x91, 0x29, + 0x05, 0x28, 0xE8, 0x87, 0xAA, 0x29, 0x05, 0x28, + 0xE8, 0x87, 0xB3, 0x29, 0x03, 0xE5, 0x95, 0x8F, + 0x03, 0xE5, 0xB9, 0xBC, 0x03, 0xE7, 0xAE, 0x8F, + 0x03, 0x50, 0x54, 0x45, 0x02, 0x32, 0x31, 0x02, + // Bytes 20c0 - 20ff + 0x32, 0x32, 0x02, 0x32, 0x33, 0x02, 0x32, 0x34, + 0x02, 0x32, 0x35, 0x02, 0x32, 0x36, 0x02, 0x32, + 0x37, 0x02, 0x32, 0x38, 0x02, 0x32, 0x39, 0x02, + 0x33, 0x30, 0x02, 0x33, 0x31, 0x02, 0x33, 0x32, + 0x02, 0x33, 0x33, 0x02, 0x33, 0x34, 0x02, 0x33, + 0x35, 0x06, 0xE1, 0x84, 0x80, 0xE1, 0x85, 0xA1, + 0x06, 0xE1, 0x84, 0x82, 0xE1, 0x85, 0xA1, 0x06, + 0xE1, 0x84, 0x83, 0xE1, 0x85, 0xA1, 0x06, 0xE1, + // Bytes 2100 - 213f + 0x84, 0x85, 0xE1, 0x85, 0xA1, 0x06, 0xE1, 0x84, + 0x86, 0xE1, 0x85, 0xA1, 0x06, 0xE1, 0x84, 0x87, + 0xE1, 0x85, 0xA1, 0x06, 0xE1, 0x84, 0x89, 0xE1, + 0x85, 0xA1, 0x06, 0xE1, 0x84, 0x8B, 0xE1, 0x85, + 0xA1, 0x06, 0xE1, 0x84, 0x8C, 0xE1, 0x85, 0xA1, + 0x06, 0xE1, 0x84, 0x8E, 0xE1, 0x85, 0xA1, 0x06, + 0xE1, 0x84, 0x8F, 0xE1, 0x85, 0xA1, 0x06, 0xE1, + 0x84, 0x90, 0xE1, 0x85, 0xA1, 0x06, 0xE1, 0x84, + // Bytes 2140 - 217f + 0x91, 0xE1, 0x85, 0xA1, 0x06, 0xE1, 0x84, 0x92, + 0xE1, 0x85, 0xA1, 0x0F, 0xE1, 0x84, 0x8E, 0xE1, + 0x85, 0xA1, 0xE1, 0x86, 0xB7, 0xE1, 0x84, 0x80, + 0xE1, 0x85, 0xA9, 0x0C, 0xE1, 0x84, 0x8C, 0xE1, + 0x85, 0xAE, 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xB4, + 0x06, 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xAE, 0x03, + 0xE4, 0xBA, 0x94, 0x03, 0xE5, 0x85, 0xAD, 0x03, + 0xE4, 0xB8, 0x83, 0x03, 0xE4, 0xB9, 0x9D, 0x03, + // Bytes 2180 - 21bf + 0xE6, 0xA0, 0xAA, 0x03, 0xE6, 0x9C, 0x89, 0x03, + 0xE7, 0xA4, 0xBE, 0x03, 0xE5, 0x90, 0x8D, 0x03, + 0xE7, 0x89, 0xB9, 0x03, 0xE8, 0xB2, 0xA1, 0x03, + 0xE7, 0xA5, 0x9D, 0x03, 0xE5, 0x8A, 0xB4, 0x03, + 0xE7, 0xA7, 0x98, 0x03, 0xE7, 0x94, 0xB7, 0x03, + 0xE9, 0x81, 0xA9, 0x03, 0xE5, 0x84, 0xAA, 0x03, + 0xE5, 0x8D, 0xB0, 0x03, 0xE6, 0xB3, 0xA8, 0x03, + 0xE9, 0xA0, 0x85, 0x03, 0xE4, 0xBC, 0x91, 0x03, + // Bytes 21c0 - 21ff + 0xE5, 0x86, 0x99, 0x03, 0xE6, 0xAD, 0xA3, 0x03, + 0xE5, 0xB7, 0xA6, 0x03, 0xE5, 0x8F, 0xB3, 0x03, + 0xE5, 0x8C, 0xBB, 0x03, 0xE5, 0xAE, 0x97, 0x03, + 0xE5, 0xAD, 0xA6, 0x03, 0xE7, 0x9B, 0xA3, 0x03, + 0xE4, 0xBC, 0x81, 0x03, 0xE8, 0xB3, 0x87, 0x03, + 0xE5, 0x8D, 0x94, 0x03, 0xE5, 0xA4, 0x9C, 0x02, + 0x33, 0x36, 0x02, 0x33, 0x37, 0x02, 0x33, 0x38, + 0x02, 0x33, 0x39, 0x02, 0x34, 0x30, 0x02, 0x34, + // Bytes 2200 - 223f + 0x31, 0x02, 0x34, 0x32, 0x02, 0x34, 0x33, 0x02, + 0x34, 0x34, 0x02, 0x34, 0x35, 0x02, 0x34, 0x36, + 0x02, 0x34, 0x37, 0x02, 0x34, 0x38, 0x02, 0x34, + 0x39, 0x02, 0x35, 0x30, 0x04, 0x31, 0xE6, 0x9C, + 0x88, 0x04, 0x32, 0xE6, 0x9C, 0x88, 0x04, 0x33, + 0xE6, 0x9C, 0x88, 0x04, 0x34, 0xE6, 0x9C, 0x88, + 0x04, 0x35, 0xE6, 0x9C, 0x88, 0x04, 0x36, 0xE6, + 0x9C, 0x88, 0x04, 0x37, 0xE6, 0x9C, 0x88, 0x04, + // Bytes 2240 - 227f + 0x38, 0xE6, 0x9C, 0x88, 0x04, 0x39, 0xE6, 0x9C, + 0x88, 0x05, 0x31, 0x30, 0xE6, 0x9C, 0x88, 0x05, + 0x31, 0x31, 0xE6, 0x9C, 0x88, 0x05, 0x31, 0x32, + 0xE6, 0x9C, 0x88, 0x02, 0x48, 0x67, 0x03, 0x65, + 0x72, 0x67, 0x02, 0x65, 0x56, 0x03, 0x4C, 0x54, + 0x44, 0x03, 0xE3, 0x82, 0xA2, 0x03, 0xE3, 0x82, + 0xA4, 0x03, 0xE3, 0x82, 0xA6, 0x03, 0xE3, 0x82, + 0xA8, 0x03, 0xE3, 0x82, 0xAA, 0x03, 0xE3, 0x82, + // Bytes 2280 - 22bf + 0xAB, 0x03, 0xE3, 0x82, 0xAD, 0x03, 0xE3, 0x82, + 0xAF, 0x03, 0xE3, 0x82, 0xB1, 0x03, 0xE3, 0x82, + 0xB3, 0x03, 0xE3, 0x82, 0xB5, 0x03, 0xE3, 0x82, + 0xB7, 0x03, 0xE3, 0x82, 0xB9, 0x03, 0xE3, 0x82, + 0xBB, 0x03, 0xE3, 0x82, 0xBD, 0x03, 0xE3, 0x82, + 0xBF, 0x03, 0xE3, 0x83, 0x81, 0x03, 0xE3, 0x83, + 0x84, 0x03, 0xE3, 0x83, 0x86, 0x03, 0xE3, 0x83, + 0x88, 0x03, 0xE3, 0x83, 0x8A, 0x03, 0xE3, 0x83, + // Bytes 22c0 - 22ff + 0x8B, 0x03, 0xE3, 0x83, 0x8C, 0x03, 0xE3, 0x83, + 0x8D, 0x03, 0xE3, 0x83, 0x8E, 0x03, 0xE3, 0x83, + 0x8F, 0x03, 0xE3, 0x83, 0x92, 0x03, 0xE3, 0x83, + 0x95, 0x03, 0xE3, 0x83, 0x98, 0x03, 0xE3, 0x83, + 0x9B, 0x03, 0xE3, 0x83, 0x9E, 0x03, 0xE3, 0x83, + 0x9F, 0x03, 0xE3, 0x83, 0xA0, 0x03, 0xE3, 0x83, + 0xA1, 0x03, 0xE3, 0x83, 0xA2, 0x03, 0xE3, 0x83, + 0xA4, 0x03, 0xE3, 0x83, 0xA6, 0x03, 0xE3, 0x83, + // Bytes 2300 - 233f + 0xA8, 0x03, 0xE3, 0x83, 0xA9, 0x03, 0xE3, 0x83, + 0xAA, 0x03, 0xE3, 0x83, 0xAB, 0x03, 0xE3, 0x83, + 0xAC, 0x03, 0xE3, 0x83, 0xAD, 0x03, 0xE3, 0x83, + 0xAF, 0x03, 0xE3, 0x83, 0xB0, 0x03, 0xE3, 0x83, + 0xB1, 0x03, 0xE3, 0x83, 0xB2, 0x0F, 0xE3, 0x82, + 0xA2, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A, 0xE3, + 0x83, 0xBC, 0xE3, 0x83, 0x88, 0x0C, 0xE3, 0x82, + 0xA2, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x95, 0xE3, + // Bytes 2340 - 237f + 0x82, 0xA1, 0x0F, 0xE3, 0x82, 0xA2, 0xE3, 0x83, + 0xB3, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, + 0x82, 0xA2, 0x09, 0xE3, 0x82, 0xA2, 0xE3, 0x83, + 0xBC, 0xE3, 0x83, 0xAB, 0x0F, 0xE3, 0x82, 0xA4, + 0xE3, 0x83, 0x8B, 0xE3, 0x83, 0xB3, 0xE3, 0x82, + 0xAF, 0xE3, 0x82, 0x99, 0x09, 0xE3, 0x82, 0xA4, + 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x81, 0x09, 0xE3, + 0x82, 0xA6, 0xE3, 0x82, 0xA9, 0xE3, 0x83, 0xB3, + // Bytes 2380 - 23bf + 0x12, 0xE3, 0x82, 0xA8, 0xE3, 0x82, 0xB9, 0xE3, + 0x82, 0xAF, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, + 0xE3, 0x82, 0x99, 0x0C, 0xE3, 0x82, 0xA8, 0xE3, + 0x83, 0xBC, 0xE3, 0x82, 0xAB, 0xE3, 0x83, 0xBC, + 0x09, 0xE3, 0x82, 0xAA, 0xE3, 0x83, 0xB3, 0xE3, + 0x82, 0xB9, 0x09, 0xE3, 0x82, 0xAA, 0xE3, 0x83, + 0xBC, 0xE3, 0x83, 0xA0, 0x09, 0xE3, 0x82, 0xAB, + 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xAA, 0x0C, 0xE3, + // Bytes 23c0 - 23ff + 0x82, 0xAB, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0x83, + 0xE3, 0x83, 0x88, 0x0C, 0xE3, 0x82, 0xAB, 0xE3, + 0x83, 0xAD, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xBC, + 0x0C, 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0xE3, + 0x83, 0xAD, 0xE3, 0x83, 0xB3, 0x0C, 0xE3, 0x82, + 0xAB, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xB3, 0xE3, + 0x83, 0x9E, 0x0C, 0xE3, 0x82, 0xAD, 0xE3, 0x82, + 0x99, 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0x0C, + // Bytes 2400 - 243f + 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0x99, 0xE3, 0x83, + 0x8B, 0xE3, 0x83, 0xBC, 0x0C, 0xE3, 0x82, 0xAD, + 0xE3, 0x83, 0xA5, 0xE3, 0x83, 0xAA, 0xE3, 0x83, + 0xBC, 0x12, 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0x99, + 0xE3, 0x83, 0xAB, 0xE3, 0x82, 0xBF, 0xE3, 0x82, + 0x99, 0xE3, 0x83, 0xBC, 0x06, 0xE3, 0x82, 0xAD, + 0xE3, 0x83, 0xAD, 0x12, 0xE3, 0x82, 0xAD, 0xE3, + 0x83, 0xAD, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, + // Bytes 2440 - 247f + 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xA0, 0x12, 0xE3, + 0x82, 0xAD, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xA1, + 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3, 0x83, + 0xAB, 0x0F, 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xAD, + 0xE3, 0x83, 0xAF, 0xE3, 0x83, 0x83, 0xE3, 0x83, + 0x88, 0x0C, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, + 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xA0, 0x12, 0xE3, + 0x82, 0xAF, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xA9, + // Bytes 2480 - 24bf + 0xE3, 0x83, 0xA0, 0xE3, 0x83, 0x88, 0xE3, 0x83, + 0xB3, 0x12, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAB, + 0xE3, 0x82, 0xBB, 0xE3, 0x82, 0x99, 0xE3, 0x82, + 0xA4, 0xE3, 0x83, 0xAD, 0x0C, 0xE3, 0x82, 0xAF, + 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xBC, 0xE3, 0x83, + 0x8D, 0x09, 0xE3, 0x82, 0xB1, 0xE3, 0x83, 0xBC, + 0xE3, 0x82, 0xB9, 0x09, 0xE3, 0x82, 0xB3, 0xE3, + 0x83, 0xAB, 0xE3, 0x83, 0x8A, 0x0C, 0xE3, 0x82, + // Bytes 24c0 - 24ff + 0xB3, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x9B, 0xE3, + 0x82, 0x9A, 0x0C, 0xE3, 0x82, 0xB5, 0xE3, 0x82, + 0xA4, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAB, 0x0F, + 0xE3, 0x82, 0xB5, 0xE3, 0x83, 0xB3, 0xE3, 0x83, + 0x81, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xA0, 0x0F, + 0xE3, 0x82, 0xB7, 0xE3, 0x83, 0xAA, 0xE3, 0x83, + 0xB3, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, 0x09, + 0xE3, 0x82, 0xBB, 0xE3, 0x83, 0xB3, 0xE3, 0x83, + // Bytes 2500 - 253f + 0x81, 0x09, 0xE3, 0x82, 0xBB, 0xE3, 0x83, 0xB3, + 0xE3, 0x83, 0x88, 0x0C, 0xE3, 0x82, 0xBF, 0xE3, + 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xB9, + 0x09, 0xE3, 0x83, 0x86, 0xE3, 0x82, 0x99, 0xE3, + 0x82, 0xB7, 0x09, 0xE3, 0x83, 0x88, 0xE3, 0x82, + 0x99, 0xE3, 0x83, 0xAB, 0x06, 0xE3, 0x83, 0x88, + 0xE3, 0x83, 0xB3, 0x06, 0xE3, 0x83, 0x8A, 0xE3, + 0x83, 0x8E, 0x09, 0xE3, 0x83, 0x8E, 0xE3, 0x83, + // Bytes 2540 - 257f + 0x83, 0xE3, 0x83, 0x88, 0x09, 0xE3, 0x83, 0x8F, + 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0x84, 0x12, 0xE3, + 0x83, 0x8F, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, + 0xE3, 0x82, 0xBB, 0xE3, 0x83, 0xB3, 0xE3, 0x83, + 0x88, 0x0C, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A, + 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x84, 0x0F, 0xE3, + 0x83, 0x8F, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, + 0xE3, 0x83, 0xAC, 0xE3, 0x83, 0xAB, 0x12, 0xE3, + // Bytes 2580 - 25bf + 0x83, 0x92, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xA2, + 0xE3, 0x82, 0xB9, 0xE3, 0x83, 0x88, 0xE3, 0x83, + 0xAB, 0x0C, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x9A, + 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAB, 0x09, 0xE3, + 0x83, 0x92, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xB3, + 0x09, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x99, 0xE3, + 0x83, 0xAB, 0x12, 0xE3, 0x83, 0x95, 0xE3, 0x82, + 0xA1, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0x83, 0xE3, + // Bytes 25c0 - 25ff + 0x83, 0x88, 0xE3, 0x82, 0x99, 0x0C, 0xE3, 0x83, + 0x95, 0xE3, 0x82, 0xA3, 0xE3, 0x83, 0xBC, 0xE3, + 0x83, 0x88, 0x12, 0xE3, 0x83, 0x95, 0xE3, 0x82, + 0x99, 0xE3, 0x83, 0x83, 0xE3, 0x82, 0xB7, 0xE3, + 0x82, 0xA7, 0xE3, 0x83, 0xAB, 0x09, 0xE3, 0x83, + 0x95, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xB3, 0x0F, + 0xE3, 0x83, 0x98, 0xE3, 0x82, 0xAF, 0xE3, 0x82, + 0xBF, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0x09, + // Bytes 2600 - 263f + 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x82, + 0xBD, 0x0C, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, + 0xE3, 0x83, 0x8B, 0xE3, 0x83, 0x92, 0x09, 0xE3, + 0x83, 0x98, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x84, + 0x0C, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, + 0x83, 0xB3, 0xE3, 0x82, 0xB9, 0x0F, 0xE3, 0x83, + 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0xE3, + 0x82, 0xB7, 0xE3, 0x82, 0x99, 0x0C, 0xE3, 0x83, + // Bytes 2640 - 267f + 0x98, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, + 0x82, 0xBF, 0x0F, 0xE3, 0x83, 0x9B, 0xE3, 0x82, + 0x9A, 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xB3, 0xE3, + 0x83, 0x88, 0x0C, 0xE3, 0x83, 0x9B, 0xE3, 0x82, + 0x99, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x88, 0x06, + 0xE3, 0x83, 0x9B, 0xE3, 0x83, 0xB3, 0x0F, 0xE3, + 0x83, 0x9B, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xB3, + 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x09, 0xE3, + // Bytes 2680 - 26bf + 0x83, 0x9B, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, + 0x09, 0xE3, 0x83, 0x9B, 0xE3, 0x83, 0xBC, 0xE3, + 0x83, 0xB3, 0x0C, 0xE3, 0x83, 0x9E, 0xE3, 0x82, + 0xA4, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAD, 0x09, + 0xE3, 0x83, 0x9E, 0xE3, 0x82, 0xA4, 0xE3, 0x83, + 0xAB, 0x09, 0xE3, 0x83, 0x9E, 0xE3, 0x83, 0x83, + 0xE3, 0x83, 0x8F, 0x09, 0xE3, 0x83, 0x9E, 0xE3, + 0x83, 0xAB, 0xE3, 0x82, 0xAF, 0x0F, 0xE3, 0x83, + // Bytes 26c0 - 26ff + 0x9E, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xB7, 0xE3, + 0x83, 0xA7, 0xE3, 0x83, 0xB3, 0x0C, 0xE3, 0x83, + 0x9F, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAD, 0xE3, + 0x83, 0xB3, 0x06, 0xE3, 0x83, 0x9F, 0xE3, 0x83, + 0xAA, 0x12, 0xE3, 0x83, 0x9F, 0xE3, 0x83, 0xAA, + 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x99, 0xE3, 0x83, + 0xBC, 0xE3, 0x83, 0xAB, 0x09, 0xE3, 0x83, 0xA1, + 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0x0F, 0xE3, + // Bytes 2700 - 273f + 0x83, 0xA1, 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, + 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xB3, 0x0C, 0xE3, + 0x83, 0xA1, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, + 0xE3, 0x83, 0xAB, 0x0C, 0xE3, 0x83, 0xA4, 0xE3, + 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, + 0x09, 0xE3, 0x83, 0xA4, 0xE3, 0x83, 0xBC, 0xE3, + 0x83, 0xAB, 0x09, 0xE3, 0x83, 0xA6, 0xE3, 0x82, + 0xA2, 0xE3, 0x83, 0xB3, 0x0C, 0xE3, 0x83, 0xAA, + // Bytes 2740 - 277f + 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, 0xE3, 0x83, + 0xAB, 0x06, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xA9, + 0x0C, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x92, 0xE3, + 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0x0F, 0xE3, 0x83, + 0xAB, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x95, 0xE3, + 0x82, 0x99, 0xE3, 0x83, 0xAB, 0x06, 0xE3, 0x83, + 0xAC, 0xE3, 0x83, 0xA0, 0x12, 0xE3, 0x83, 0xAC, + 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x88, 0xE3, 0x82, + // Bytes 2780 - 27bf + 0xB1, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xB3, 0x09, + 0xE3, 0x83, 0xAF, 0xE3, 0x83, 0x83, 0xE3, 0x83, + 0x88, 0x04, 0x30, 0xE7, 0x82, 0xB9, 0x04, 0x31, + 0xE7, 0x82, 0xB9, 0x04, 0x32, 0xE7, 0x82, 0xB9, + 0x04, 0x33, 0xE7, 0x82, 0xB9, 0x04, 0x34, 0xE7, + 0x82, 0xB9, 0x04, 0x35, 0xE7, 0x82, 0xB9, 0x04, + 0x36, 0xE7, 0x82, 0xB9, 0x04, 0x37, 0xE7, 0x82, + 0xB9, 0x04, 0x38, 0xE7, 0x82, 0xB9, 0x04, 0x39, + // Bytes 27c0 - 27ff + 0xE7, 0x82, 0xB9, 0x05, 0x31, 0x30, 0xE7, 0x82, + 0xB9, 0x05, 0x31, 0x31, 0xE7, 0x82, 0xB9, 0x05, + 0x31, 0x32, 0xE7, 0x82, 0xB9, 0x05, 0x31, 0x33, + 0xE7, 0x82, 0xB9, 0x05, 0x31, 0x34, 0xE7, 0x82, + 0xB9, 0x05, 0x31, 0x35, 0xE7, 0x82, 0xB9, 0x05, + 0x31, 0x36, 0xE7, 0x82, 0xB9, 0x05, 0x31, 0x37, + 0xE7, 0x82, 0xB9, 0x05, 0x31, 0x38, 0xE7, 0x82, + 0xB9, 0x05, 0x31, 0x39, 0xE7, 0x82, 0xB9, 0x05, + // Bytes 2800 - 283f + 0x32, 0x30, 0xE7, 0x82, 0xB9, 0x05, 0x32, 0x31, + 0xE7, 0x82, 0xB9, 0x05, 0x32, 0x32, 0xE7, 0x82, + 0xB9, 0x05, 0x32, 0x33, 0xE7, 0x82, 0xB9, 0x05, + 0x32, 0x34, 0xE7, 0x82, 0xB9, 0x03, 0x68, 0x50, + 0x61, 0x02, 0x64, 0x61, 0x02, 0x41, 0x55, 0x03, + 0x62, 0x61, 0x72, 0x02, 0x6F, 0x56, 0x02, 0x70, + 0x63, 0x02, 0x64, 0x6D, 0x03, 0x64, 0x6D, 0x32, + 0x03, 0x64, 0x6D, 0x33, 0x02, 0x49, 0x55, 0x06, + // Bytes 2840 - 287f + 0xE5, 0xB9, 0xB3, 0xE6, 0x88, 0x90, 0x06, 0xE6, + 0x98, 0xAD, 0xE5, 0x92, 0x8C, 0x06, 0xE5, 0xA4, + 0xA7, 0xE6, 0xAD, 0xA3, 0x06, 0xE6, 0x98, 0x8E, + 0xE6, 0xB2, 0xBB, 0x0C, 0xE6, 0xA0, 0xAA, 0xE5, + 0xBC, 0x8F, 0xE4, 0xBC, 0x9A, 0xE7, 0xA4, 0xBE, + 0x02, 0x70, 0x41, 0x02, 0x6E, 0x41, 0x03, 0xCE, + 0xBC, 0x41, 0x02, 0x6D, 0x41, 0x02, 0x6B, 0x41, + 0x02, 0x4B, 0x42, 0x02, 0x4D, 0x42, 0x02, 0x47, + // Bytes 2880 - 28bf + 0x42, 0x03, 0x63, 0x61, 0x6C, 0x04, 0x6B, 0x63, + 0x61, 0x6C, 0x02, 0x70, 0x46, 0x02, 0x6E, 0x46, + 0x03, 0xCE, 0xBC, 0x46, 0x03, 0xCE, 0xBC, 0x67, + 0x02, 0x6D, 0x67, 0x02, 0x6B, 0x67, 0x02, 0x48, + 0x7A, 0x03, 0x6B, 0x48, 0x7A, 0x03, 0x4D, 0x48, + 0x7A, 0x03, 0x47, 0x48, 0x7A, 0x03, 0x54, 0x48, + 0x7A, 0x03, 0xCE, 0xBC, 0x6C, 0x02, 0x6D, 0x6C, + 0x02, 0x64, 0x6C, 0x02, 0x6B, 0x6C, 0x02, 0x66, + // Bytes 28c0 - 28ff + 0x6D, 0x02, 0x6E, 0x6D, 0x03, 0xCE, 0xBC, 0x6D, + 0x02, 0x6D, 0x6D, 0x02, 0x63, 0x6D, 0x02, 0x6B, + 0x6D, 0x03, 0x6D, 0x6D, 0x32, 0x03, 0x63, 0x6D, + 0x32, 0x02, 0x6D, 0x32, 0x03, 0x6B, 0x6D, 0x32, + 0x03, 0x6D, 0x6D, 0x33, 0x03, 0x63, 0x6D, 0x33, + 0x02, 0x6D, 0x33, 0x03, 0x6B, 0x6D, 0x33, 0x05, + 0x6D, 0xE2, 0x88, 0x95, 0x73, 0x06, 0x6D, 0xE2, + 0x88, 0x95, 0x73, 0x32, 0x02, 0x50, 0x61, 0x03, + // Bytes 2900 - 293f + 0x6B, 0x50, 0x61, 0x03, 0x4D, 0x50, 0x61, 0x03, + 0x47, 0x50, 0x61, 0x03, 0x72, 0x61, 0x64, 0x07, + 0x72, 0x61, 0x64, 0xE2, 0x88, 0x95, 0x73, 0x08, + 0x72, 0x61, 0x64, 0xE2, 0x88, 0x95, 0x73, 0x32, + 0x02, 0x70, 0x73, 0x02, 0x6E, 0x73, 0x03, 0xCE, + 0xBC, 0x73, 0x02, 0x6D, 0x73, 0x02, 0x70, 0x56, + 0x02, 0x6E, 0x56, 0x03, 0xCE, 0xBC, 0x56, 0x02, + 0x6D, 0x56, 0x02, 0x6B, 0x56, 0x02, 0x4D, 0x56, + // Bytes 2940 - 297f + 0x02, 0x70, 0x57, 0x02, 0x6E, 0x57, 0x03, 0xCE, + 0xBC, 0x57, 0x02, 0x6D, 0x57, 0x02, 0x6B, 0x57, + 0x02, 0x4D, 0x57, 0x03, 0x6B, 0xCE, 0xA9, 0x03, + 0x4D, 0xCE, 0xA9, 0x04, 0x61, 0x2E, 0x6D, 0x2E, + 0x02, 0x42, 0x71, 0x02, 0x63, 0x63, 0x02, 0x63, + 0x64, 0x06, 0x43, 0xE2, 0x88, 0x95, 0x6B, 0x67, + 0x03, 0x43, 0x6F, 0x2E, 0x02, 0x64, 0x42, 0x02, + 0x47, 0x79, 0x02, 0x68, 0x61, 0x02, 0x48, 0x50, + // Bytes 2980 - 29bf + 0x02, 0x69, 0x6E, 0x02, 0x4B, 0x4B, 0x02, 0x4B, + 0x4D, 0x02, 0x6B, 0x74, 0x02, 0x6C, 0x6D, 0x02, + 0x6C, 0x6E, 0x03, 0x6C, 0x6F, 0x67, 0x02, 0x6C, + 0x78, 0x02, 0x6D, 0x62, 0x03, 0x6D, 0x69, 0x6C, + 0x03, 0x6D, 0x6F, 0x6C, 0x02, 0x50, 0x48, 0x04, + 0x70, 0x2E, 0x6D, 0x2E, 0x03, 0x50, 0x50, 0x4D, + 0x02, 0x50, 0x52, 0x02, 0x73, 0x72, 0x02, 0x53, + 0x76, 0x02, 0x57, 0x62, 0x05, 0x56, 0xE2, 0x88, + // Bytes 29c0 - 29ff + 0x95, 0x6D, 0x05, 0x41, 0xE2, 0x88, 0x95, 0x6D, + 0x04, 0x31, 0xE6, 0x97, 0xA5, 0x04, 0x32, 0xE6, + 0x97, 0xA5, 0x04, 0x33, 0xE6, 0x97, 0xA5, 0x04, + 0x34, 0xE6, 0x97, 0xA5, 0x04, 0x35, 0xE6, 0x97, + 0xA5, 0x04, 0x36, 0xE6, 0x97, 0xA5, 0x04, 0x37, + 0xE6, 0x97, 0xA5, 0x04, 0x38, 0xE6, 0x97, 0xA5, + 0x04, 0x39, 0xE6, 0x97, 0xA5, 0x05, 0x31, 0x30, + 0xE6, 0x97, 0xA5, 0x05, 0x31, 0x31, 0xE6, 0x97, + // Bytes 2a00 - 2a3f + 0xA5, 0x05, 0x31, 0x32, 0xE6, 0x97, 0xA5, 0x05, + 0x31, 0x33, 0xE6, 0x97, 0xA5, 0x05, 0x31, 0x34, + 0xE6, 0x97, 0xA5, 0x05, 0x31, 0x35, 0xE6, 0x97, + 0xA5, 0x05, 0x31, 0x36, 0xE6, 0x97, 0xA5, 0x05, + 0x31, 0x37, 0xE6, 0x97, 0xA5, 0x05, 0x31, 0x38, + 0xE6, 0x97, 0xA5, 0x05, 0x31, 0x39, 0xE6, 0x97, + 0xA5, 0x05, 0x32, 0x30, 0xE6, 0x97, 0xA5, 0x05, + 0x32, 0x31, 0xE6, 0x97, 0xA5, 0x05, 0x32, 0x32, + // Bytes 2a40 - 2a7f + 0xE6, 0x97, 0xA5, 0x05, 0x32, 0x33, 0xE6, 0x97, + 0xA5, 0x05, 0x32, 0x34, 0xE6, 0x97, 0xA5, 0x05, + 0x32, 0x35, 0xE6, 0x97, 0xA5, 0x05, 0x32, 0x36, + 0xE6, 0x97, 0xA5, 0x05, 0x32, 0x37, 0xE6, 0x97, + 0xA5, 0x05, 0x32, 0x38, 0xE6, 0x97, 0xA5, 0x05, + 0x32, 0x39, 0xE6, 0x97, 0xA5, 0x05, 0x33, 0x30, + 0xE6, 0x97, 0xA5, 0x05, 0x33, 0x31, 0xE6, 0x97, + 0xA5, 0x03, 0x67, 0x61, 0x6C, 0x03, 0xEA, 0x9D, + // Bytes 2a80 - 2abf + 0xAF, 0x03, 0xE8, 0xB1, 0x88, 0x03, 0xE6, 0x9B, + 0xB4, 0x03, 0xE8, 0xB3, 0x88, 0x03, 0xE6, 0xBB, + 0x91, 0x03, 0xE4, 0xB8, 0xB2, 0x03, 0xE5, 0x8F, + 0xA5, 0x03, 0xE5, 0xA5, 0x91, 0x03, 0xE5, 0x96, + 0x87, 0x03, 0xE5, 0xA5, 0x88, 0x03, 0xE6, 0x87, + 0xB6, 0x03, 0xE7, 0x99, 0xA9, 0x03, 0xE7, 0xBE, + 0x85, 0x03, 0xE8, 0x98, 0xBF, 0x03, 0xE8, 0x9E, + 0xBA, 0x03, 0xE8, 0xA3, 0xB8, 0x03, 0xE9, 0x82, + // Bytes 2ac0 - 2aff + 0x8F, 0x03, 0xE6, 0xA8, 0x82, 0x03, 0xE6, 0xB4, + 0x9B, 0x03, 0xE7, 0x83, 0x99, 0x03, 0xE7, 0x8F, + 0x9E, 0x03, 0xE8, 0x90, 0xBD, 0x03, 0xE9, 0x85, + 0xAA, 0x03, 0xE9, 0xA7, 0xB1, 0x03, 0xE4, 0xBA, + 0x82, 0x03, 0xE5, 0x8D, 0xB5, 0x03, 0xE6, 0xAC, + 0x84, 0x03, 0xE7, 0x88, 0x9B, 0x03, 0xE8, 0x98, + 0xAD, 0x03, 0xE9, 0xB8, 0x9E, 0x03, 0xE5, 0xB5, + 0x90, 0x03, 0xE6, 0xBF, 0xAB, 0x03, 0xE8, 0x97, + // Bytes 2b00 - 2b3f + 0x8D, 0x03, 0xE8, 0xA5, 0xA4, 0x03, 0xE6, 0x8B, + 0x89, 0x03, 0xE8, 0x87, 0x98, 0x03, 0xE8, 0xA0, + 0x9F, 0x03, 0xE5, 0xBB, 0x8A, 0x03, 0xE6, 0x9C, + 0x97, 0x03, 0xE6, 0xB5, 0xAA, 0x03, 0xE7, 0x8B, + 0xBC, 0x03, 0xE9, 0x83, 0x8E, 0x03, 0xE4, 0xBE, + 0x86, 0x03, 0xE5, 0x86, 0xB7, 0x03, 0xE5, 0x8B, + 0x9E, 0x03, 0xE6, 0x93, 0x84, 0x03, 0xE6, 0xAB, + 0x93, 0x03, 0xE7, 0x88, 0x90, 0x03, 0xE7, 0x9B, + // Bytes 2b40 - 2b7f + 0xA7, 0x03, 0xE8, 0x98, 0x86, 0x03, 0xE8, 0x99, + 0x9C, 0x03, 0xE8, 0xB7, 0xAF, 0x03, 0xE9, 0x9C, + 0xB2, 0x03, 0xE9, 0xAD, 0xAF, 0x03, 0xE9, 0xB7, + 0xBA, 0x03, 0xE7, 0xA2, 0x8C, 0x03, 0xE7, 0xA5, + 0xBF, 0x03, 0xE7, 0xB6, 0xA0, 0x03, 0xE8, 0x8F, + 0x89, 0x03, 0xE9, 0x8C, 0x84, 0x03, 0xE8, 0xAB, + 0x96, 0x03, 0xE5, 0xA3, 0x9F, 0x03, 0xE5, 0xBC, + 0x84, 0x03, 0xE7, 0xB1, 0xA0, 0x03, 0xE8, 0x81, + // Bytes 2b80 - 2bbf + 0xBE, 0x03, 0xE7, 0x89, 0xA2, 0x03, 0xE7, 0xA3, + 0x8A, 0x03, 0xE8, 0xB3, 0x82, 0x03, 0xE9, 0x9B, + 0xB7, 0x03, 0xE5, 0xA3, 0x98, 0x03, 0xE5, 0xB1, + 0xA2, 0x03, 0xE6, 0xA8, 0x93, 0x03, 0xE6, 0xB7, + 0x9A, 0x03, 0xE6, 0xBC, 0x8F, 0x03, 0xE7, 0xB4, + 0xAF, 0x03, 0xE7, 0xB8, 0xB7, 0x03, 0xE9, 0x99, + 0x8B, 0x03, 0xE5, 0x8B, 0x92, 0x03, 0xE8, 0x82, + 0x8B, 0x03, 0xE5, 0x87, 0x9C, 0x03, 0xE5, 0x87, + // Bytes 2bc0 - 2bff + 0x8C, 0x03, 0xE7, 0xA8, 0x9C, 0x03, 0xE7, 0xB6, + 0xBE, 0x03, 0xE8, 0x8F, 0xB1, 0x03, 0xE9, 0x99, + 0xB5, 0x03, 0xE8, 0xAE, 0x80, 0x03, 0xE6, 0x8B, + 0x8F, 0x03, 0xE8, 0xAB, 0xBE, 0x03, 0xE4, 0xB8, + 0xB9, 0x03, 0xE5, 0xAF, 0xA7, 0x03, 0xE6, 0x80, + 0x92, 0x03, 0xE7, 0x8E, 0x87, 0x03, 0xE7, 0x95, + 0xB0, 0x03, 0xE5, 0x8C, 0x97, 0x03, 0xE7, 0xA3, + 0xBB, 0x03, 0xE4, 0xBE, 0xBF, 0x03, 0xE5, 0xBE, + // Bytes 2c00 - 2c3f + 0xA9, 0x03, 0xE4, 0xB8, 0x8D, 0x03, 0xE6, 0xB3, + 0x8C, 0x03, 0xE6, 0x95, 0xB8, 0x03, 0xE7, 0xB4, + 0xA2, 0x03, 0xE5, 0x8F, 0x83, 0x03, 0xE5, 0xA1, + 0x9E, 0x03, 0xE7, 0x9C, 0x81, 0x03, 0xE8, 0x91, + 0x89, 0x03, 0xE8, 0xAA, 0xAA, 0x03, 0xE6, 0xAE, + 0xBA, 0x03, 0xE6, 0xB2, 0x88, 0x03, 0xE6, 0x8B, + 0xBE, 0x03, 0xE8, 0x8B, 0xA5, 0x03, 0xE6, 0x8E, + 0xA0, 0x03, 0xE7, 0x95, 0xA5, 0x03, 0xE4, 0xBA, + // Bytes 2c40 - 2c7f + 0xAE, 0x03, 0xE5, 0x85, 0xA9, 0x03, 0xE5, 0x87, + 0x89, 0x03, 0xE6, 0xA2, 0x81, 0x03, 0xE7, 0xB3, + 0xA7, 0x03, 0xE8, 0x89, 0xAF, 0x03, 0xE8, 0xAB, + 0x92, 0x03, 0xE9, 0x87, 0x8F, 0x03, 0xE5, 0x8B, + 0xB5, 0x03, 0xE5, 0x91, 0x82, 0x03, 0xE5, 0xBB, + 0xAC, 0x03, 0xE6, 0x97, 0x85, 0x03, 0xE6, 0xBF, + 0xBE, 0x03, 0xE7, 0xA4, 0xAA, 0x03, 0xE9, 0x96, + 0xAD, 0x03, 0xE9, 0xA9, 0xAA, 0x03, 0xE9, 0xBA, + // Bytes 2c80 - 2cbf + 0x97, 0x03, 0xE9, 0xBB, 0x8E, 0x03, 0xE6, 0x9B, + 0x86, 0x03, 0xE6, 0xAD, 0xB7, 0x03, 0xE8, 0xBD, + 0xA2, 0x03, 0xE5, 0xB9, 0xB4, 0x03, 0xE6, 0x86, + 0x90, 0x03, 0xE6, 0x88, 0x80, 0x03, 0xE6, 0x92, + 0x9A, 0x03, 0xE6, 0xBC, 0xA3, 0x03, 0xE7, 0x85, + 0x89, 0x03, 0xE7, 0x92, 0x89, 0x03, 0xE7, 0xA7, + 0x8A, 0x03, 0xE7, 0xB7, 0xB4, 0x03, 0xE8, 0x81, + 0xAF, 0x03, 0xE8, 0xBC, 0xA6, 0x03, 0xE8, 0x93, + // Bytes 2cc0 - 2cff + 0xAE, 0x03, 0xE9, 0x80, 0xA3, 0x03, 0xE9, 0x8D, + 0x8A, 0x03, 0xE5, 0x88, 0x97, 0x03, 0xE5, 0x8A, + 0xA3, 0x03, 0xE5, 0x92, 0xBD, 0x03, 0xE7, 0x83, + 0x88, 0x03, 0xE8, 0xA3, 0x82, 0x03, 0xE5, 0xBB, + 0x89, 0x03, 0xE5, 0xBF, 0xB5, 0x03, 0xE6, 0x8D, + 0xBB, 0x03, 0xE6, 0xAE, 0xAE, 0x03, 0xE7, 0xB0, + 0xBE, 0x03, 0xE7, 0x8D, 0xB5, 0x03, 0xE4, 0xBB, + 0xA4, 0x03, 0xE5, 0x9B, 0xB9, 0x03, 0xE5, 0xB6, + // Bytes 2d00 - 2d3f + 0xBA, 0x03, 0xE6, 0x80, 0x9C, 0x03, 0xE7, 0x8E, + 0xB2, 0x03, 0xE7, 0x91, 0xA9, 0x03, 0xE7, 0xBE, + 0x9A, 0x03, 0xE8, 0x81, 0x86, 0x03, 0xE9, 0x88, + 0xB4, 0x03, 0xE9, 0x9B, 0xB6, 0x03, 0xE9, 0x9D, + 0x88, 0x03, 0xE9, 0xA0, 0x98, 0x03, 0xE4, 0xBE, + 0x8B, 0x03, 0xE7, 0xA6, 0xAE, 0x03, 0xE9, 0x86, + 0xB4, 0x03, 0xE9, 0x9A, 0xB8, 0x03, 0xE6, 0x83, + 0xA1, 0x03, 0xE4, 0xBA, 0x86, 0x03, 0xE5, 0x83, + // Bytes 2d40 - 2d7f + 0x9A, 0x03, 0xE5, 0xAF, 0xAE, 0x03, 0xE5, 0xB0, + 0xBF, 0x03, 0xE6, 0x96, 0x99, 0x03, 0xE7, 0x87, + 0x8E, 0x03, 0xE7, 0x99, 0x82, 0x03, 0xE8, 0x93, + 0xBC, 0x03, 0xE9, 0x81, 0xBC, 0x03, 0xE6, 0x9A, + 0x88, 0x03, 0xE9, 0x98, 0xAE, 0x03, 0xE5, 0x8A, + 0x89, 0x03, 0xE6, 0x9D, 0xBB, 0x03, 0xE6, 0x9F, + 0xB3, 0x03, 0xE6, 0xB5, 0x81, 0x03, 0xE6, 0xBA, + 0x9C, 0x03, 0xE7, 0x90, 0x89, 0x03, 0xE7, 0x95, + // Bytes 2d80 - 2dbf + 0x99, 0x03, 0xE7, 0xA1, 0xAB, 0x03, 0xE7, 0xB4, + 0x90, 0x03, 0xE9, 0xA1, 0x9E, 0x03, 0xE6, 0x88, + 0xAE, 0x03, 0xE9, 0x99, 0xB8, 0x03, 0xE5, 0x80, + 0xAB, 0x03, 0xE5, 0xB4, 0x99, 0x03, 0xE6, 0xB7, + 0xAA, 0x03, 0xE8, 0xBC, 0xAA, 0x03, 0xE5, 0xBE, + 0x8B, 0x03, 0xE6, 0x85, 0x84, 0x03, 0xE6, 0xA0, + 0x97, 0x03, 0xE9, 0x9A, 0x86, 0x03, 0xE5, 0x88, + 0xA9, 0x03, 0xE5, 0x90, 0x8F, 0x03, 0xE5, 0xB1, + // Bytes 2dc0 - 2dff + 0xA5, 0x03, 0xE6, 0x98, 0x93, 0x03, 0xE6, 0x9D, + 0x8E, 0x03, 0xE6, 0xA2, 0xA8, 0x03, 0xE6, 0xB3, + 0xA5, 0x03, 0xE7, 0x90, 0x86, 0x03, 0xE7, 0x97, + 0xA2, 0x03, 0xE7, 0xBD, 0xB9, 0x03, 0xE8, 0xA3, + 0x8F, 0x03, 0xE8, 0xA3, 0xA1, 0x03, 0xE9, 0x9B, + 0xA2, 0x03, 0xE5, 0x8C, 0xBF, 0x03, 0xE6, 0xBA, + 0xBA, 0x03, 0xE5, 0x90, 0x9D, 0x03, 0xE7, 0x87, + 0x90, 0x03, 0xE7, 0x92, 0x98, 0x03, 0xE8, 0x97, + // Bytes 2e00 - 2e3f + 0xBA, 0x03, 0xE9, 0x9A, 0xA3, 0x03, 0xE9, 0xB1, + 0x97, 0x03, 0xE9, 0xBA, 0x9F, 0x03, 0xE6, 0x9E, + 0x97, 0x03, 0xE6, 0xB7, 0x8B, 0x03, 0xE8, 0x87, + 0xA8, 0x03, 0xE7, 0xAC, 0xA0, 0x03, 0xE7, 0xB2, + 0x92, 0x03, 0xE7, 0x8B, 0x80, 0x03, 0xE7, 0x82, + 0x99, 0x03, 0xE8, 0xAD, 0x98, 0x03, 0xE4, 0xBB, + 0x80, 0x03, 0xE8, 0x8C, 0xB6, 0x03, 0xE5, 0x88, + 0xBA, 0x03, 0xE5, 0x88, 0x87, 0x03, 0xE5, 0xBA, + // Bytes 2e40 - 2e7f + 0xA6, 0x03, 0xE6, 0x8B, 0x93, 0x03, 0xE7, 0xB3, + 0x96, 0x03, 0xE5, 0xAE, 0x85, 0x03, 0xE6, 0xB4, + 0x9E, 0x03, 0xE6, 0x9A, 0xB4, 0x03, 0xE8, 0xBC, + 0xBB, 0x03, 0xE9, 0x99, 0x8D, 0x03, 0xE5, 0xBB, + 0x93, 0x03, 0xE5, 0x85, 0x80, 0x03, 0xE5, 0x97, + 0x80, 0x03, 0xE5, 0xA1, 0x9A, 0x03, 0xE6, 0x99, + 0xB4, 0x03, 0xE5, 0x87, 0x9E, 0x03, 0xE7, 0x8C, + 0xAA, 0x03, 0xE7, 0x9B, 0x8A, 0x03, 0xE7, 0xA4, + // Bytes 2e80 - 2ebf + 0xBC, 0x03, 0xE7, 0xA5, 0x9E, 0x03, 0xE7, 0xA5, + 0xA5, 0x03, 0xE7, 0xA6, 0x8F, 0x03, 0xE9, 0x9D, + 0x96, 0x03, 0xE7, 0xB2, 0xBE, 0x03, 0xE8, 0x98, + 0x92, 0x03, 0xE8, 0xAB, 0xB8, 0x03, 0xE9, 0x80, + 0xB8, 0x03, 0xE9, 0x83, 0xBD, 0x03, 0xE9, 0xA3, + 0xAF, 0x03, 0xE9, 0xA3, 0xBC, 0x03, 0xE9, 0xA4, + 0xA8, 0x03, 0xE9, 0xB6, 0xB4, 0x03, 0xE4, 0xBE, + 0xAE, 0x03, 0xE5, 0x83, 0xA7, 0x03, 0xE5, 0x85, + // Bytes 2ec0 - 2eff + 0x8D, 0x03, 0xE5, 0x8B, 0x89, 0x03, 0xE5, 0x8B, + 0xA4, 0x03, 0xE5, 0x8D, 0x91, 0x03, 0xE5, 0x96, + 0x9D, 0x03, 0xE5, 0x98, 0x86, 0x03, 0xE5, 0x99, + 0xA8, 0x03, 0xE5, 0xA1, 0x80, 0x03, 0xE5, 0xA2, + 0xA8, 0x03, 0xE5, 0xB1, 0xA4, 0x03, 0xE6, 0x82, + 0x94, 0x03, 0xE6, 0x85, 0xA8, 0x03, 0xE6, 0x86, + 0x8E, 0x03, 0xE6, 0x87, 0xB2, 0x03, 0xE6, 0x95, + 0x8F, 0x03, 0xE6, 0x97, 0xA2, 0x03, 0xE6, 0x9A, + // Bytes 2f00 - 2f3f + 0x91, 0x03, 0xE6, 0xA2, 0x85, 0x03, 0xE6, 0xB5, + 0xB7, 0x03, 0xE6, 0xB8, 0x9A, 0x03, 0xE6, 0xBC, + 0xA2, 0x03, 0xE7, 0x85, 0xAE, 0x03, 0xE7, 0x88, + 0xAB, 0x03, 0xE7, 0x90, 0xA2, 0x03, 0xE7, 0xA2, + 0x91, 0x03, 0xE7, 0xA5, 0x89, 0x03, 0xE7, 0xA5, + 0x88, 0x03, 0xE7, 0xA5, 0x90, 0x03, 0xE7, 0xA5, + 0x96, 0x03, 0xE7, 0xA6, 0x8D, 0x03, 0xE7, 0xA6, + 0x8E, 0x03, 0xE7, 0xA9, 0x80, 0x03, 0xE7, 0xAA, + // Bytes 2f40 - 2f7f + 0x81, 0x03, 0xE7, 0xAF, 0x80, 0x03, 0xE7, 0xB8, + 0x89, 0x03, 0xE7, 0xB9, 0x81, 0x03, 0xE7, 0xBD, + 0xB2, 0x03, 0xE8, 0x80, 0x85, 0x03, 0xE8, 0x87, + 0xAD, 0x03, 0xE8, 0x89, 0xB9, 0x03, 0xE8, 0x91, + 0x97, 0x03, 0xE8, 0xA4, 0x90, 0x03, 0xE8, 0xA6, + 0x96, 0x03, 0xE8, 0xAC, 0x81, 0x03, 0xE8, 0xAC, + 0xB9, 0x03, 0xE8, 0xB3, 0x93, 0x03, 0xE8, 0xB4, + 0x88, 0x03, 0xE8, 0xBE, 0xB6, 0x03, 0xE9, 0x9B, + // Bytes 2f80 - 2fbf + 0xA3, 0x03, 0xE9, 0x9F, 0xBF, 0x03, 0xE9, 0xA0, + 0xBB, 0x03, 0xE6, 0x81, 0xB5, 0x04, 0xF0, 0xA4, + 0x8B, 0xAE, 0x03, 0xE8, 0x88, 0x98, 0x03, 0xE4, + 0xB8, 0xA6, 0x03, 0xE5, 0x86, 0xB5, 0x03, 0xE5, + 0x85, 0xA8, 0x03, 0xE4, 0xBE, 0x80, 0x03, 0xE5, + 0x85, 0x85, 0x03, 0xE5, 0x86, 0x80, 0x03, 0xE5, + 0x8B, 0x87, 0x03, 0xE5, 0x8B, 0xBA, 0x03, 0xE5, + 0x95, 0x95, 0x03, 0xE5, 0x96, 0x99, 0x03, 0xE5, + // Bytes 2fc0 - 2fff + 0x97, 0xA2, 0x03, 0xE5, 0xA2, 0xB3, 0x03, 0xE5, + 0xA5, 0x84, 0x03, 0xE5, 0xA5, 0x94, 0x03, 0xE5, + 0xA9, 0xA2, 0x03, 0xE5, 0xAC, 0xA8, 0x03, 0xE5, + 0xBB, 0x92, 0x03, 0xE5, 0xBB, 0x99, 0x03, 0xE5, + 0xBD, 0xA9, 0x03, 0xE5, 0xBE, 0xAD, 0x03, 0xE6, + 0x83, 0x98, 0x03, 0xE6, 0x85, 0x8E, 0x03, 0xE6, + 0x84, 0x88, 0x03, 0xE6, 0x85, 0xA0, 0x03, 0xE6, + 0x88, 0xB4, 0x03, 0xE6, 0x8F, 0x84, 0x03, 0xE6, + // Bytes 3000 - 303f + 0x90, 0x9C, 0x03, 0xE6, 0x91, 0x92, 0x03, 0xE6, + 0x95, 0x96, 0x03, 0xE6, 0x9C, 0x9B, 0x03, 0xE6, + 0x9D, 0x96, 0x03, 0xE6, 0xBB, 0x9B, 0x03, 0xE6, + 0xBB, 0x8B, 0x03, 0xE7, 0x80, 0x9E, 0x03, 0xE7, + 0x9E, 0xA7, 0x03, 0xE7, 0x88, 0xB5, 0x03, 0xE7, + 0x8A, 0xAF, 0x03, 0xE7, 0x91, 0xB1, 0x03, 0xE7, + 0x94, 0x86, 0x03, 0xE7, 0x94, 0xBB, 0x03, 0xE7, + 0x98, 0x9D, 0x03, 0xE7, 0x98, 0x9F, 0x03, 0xE7, + // Bytes 3040 - 307f + 0x9B, 0x9B, 0x03, 0xE7, 0x9B, 0xB4, 0x03, 0xE7, + 0x9D, 0x8A, 0x03, 0xE7, 0x9D, 0x80, 0x03, 0xE7, + 0xA3, 0x8C, 0x03, 0xE7, 0xAA, 0xB1, 0x03, 0xE7, + 0xB1, 0xBB, 0x03, 0xE7, 0xB5, 0x9B, 0x03, 0xE7, + 0xBC, 0xBE, 0x03, 0xE8, 0x8D, 0x92, 0x03, 0xE8, + 0x8F, 0xAF, 0x03, 0xE8, 0x9D, 0xB9, 0x03, 0xE8, + 0xA5, 0x81, 0x03, 0xE8, 0xA6, 0x86, 0x03, 0xE8, + 0xAA, 0xBF, 0x03, 0xE8, 0xAB, 0x8B, 0x03, 0xE8, + // Bytes 3080 - 30bf + 0xAB, 0xAD, 0x03, 0xE8, 0xAE, 0x8A, 0x03, 0xE8, + 0xBC, 0xB8, 0x03, 0xE9, 0x81, 0xB2, 0x03, 0xE9, + 0x86, 0x99, 0x03, 0xE9, 0x89, 0xB6, 0x03, 0xE9, + 0x99, 0xBC, 0x03, 0xE9, 0x9F, 0x9B, 0x03, 0xE9, + 0xA0, 0x8B, 0x03, 0xE9, 0xAC, 0x92, 0x04, 0xF0, + 0xA2, 0xA1, 0x8A, 0x04, 0xF0, 0xA2, 0xA1, 0x84, + 0x04, 0xF0, 0xA3, 0x8F, 0x95, 0x03, 0xE3, 0xAE, + 0x9D, 0x03, 0xE4, 0x80, 0x98, 0x03, 0xE4, 0x80, + // Bytes 30c0 - 30ff + 0xB9, 0x04, 0xF0, 0xA5, 0x89, 0x89, 0x04, 0xF0, + 0xA5, 0xB3, 0x90, 0x04, 0xF0, 0xA7, 0xBB, 0x93, + 0x03, 0xE9, 0xBD, 0x83, 0x03, 0xE9, 0xBE, 0x8E, + 0x02, 0x66, 0x66, 0x02, 0x66, 0x69, 0x02, 0x66, + 0x6C, 0x03, 0x66, 0x66, 0x69, 0x03, 0x66, 0x66, + 0x6C, 0x02, 0x73, 0x74, 0x04, 0xD5, 0xB4, 0xD5, + 0xB6, 0x04, 0xD5, 0xB4, 0xD5, 0xA5, 0x04, 0xD5, + 0xB4, 0xD5, 0xAB, 0x04, 0xD5, 0xBE, 0xD5, 0xB6, + // Bytes 3100 - 313f + 0x04, 0xD5, 0xB4, 0xD5, 0xAD, 0x04, 0xD7, 0x99, + 0xD6, 0xB4, 0x04, 0xD7, 0xB2, 0xD6, 0xB7, 0x02, + 0xD7, 0xA2, 0x02, 0xD7, 0x94, 0x02, 0xD7, 0x9B, + 0x02, 0xD7, 0x9C, 0x02, 0xD7, 0x9D, 0x02, 0xD7, + 0xA8, 0x02, 0xD7, 0xAA, 0x04, 0xD7, 0xA9, 0xD7, + 0x81, 0x04, 0xD7, 0xA9, 0xD7, 0x82, 0x06, 0xD7, + 0xA9, 0xD6, 0xBC, 0xD7, 0x81, 0x06, 0xD7, 0xA9, + 0xD6, 0xBC, 0xD7, 0x82, 0x04, 0xD7, 0x90, 0xD6, + // Bytes 3140 - 317f + 0xB7, 0x04, 0xD7, 0x90, 0xD6, 0xB8, 0x04, 0xD7, + 0x90, 0xD6, 0xBC, 0x04, 0xD7, 0x91, 0xD6, 0xBC, + 0x04, 0xD7, 0x92, 0xD6, 0xBC, 0x04, 0xD7, 0x93, + 0xD6, 0xBC, 0x04, 0xD7, 0x94, 0xD6, 0xBC, 0x04, + 0xD7, 0x95, 0xD6, 0xBC, 0x04, 0xD7, 0x96, 0xD6, + 0xBC, 0x04, 0xD7, 0x98, 0xD6, 0xBC, 0x04, 0xD7, + 0x99, 0xD6, 0xBC, 0x04, 0xD7, 0x9A, 0xD6, 0xBC, + 0x04, 0xD7, 0x9B, 0xD6, 0xBC, 0x04, 0xD7, 0x9C, + // Bytes 3180 - 31bf + 0xD6, 0xBC, 0x04, 0xD7, 0x9E, 0xD6, 0xBC, 0x04, + 0xD7, 0xA0, 0xD6, 0xBC, 0x04, 0xD7, 0xA1, 0xD6, + 0xBC, 0x04, 0xD7, 0xA3, 0xD6, 0xBC, 0x04, 0xD7, + 0xA4, 0xD6, 0xBC, 0x04, 0xD7, 0xA6, 0xD6, 0xBC, + 0x04, 0xD7, 0xA7, 0xD6, 0xBC, 0x04, 0xD7, 0xA8, + 0xD6, 0xBC, 0x04, 0xD7, 0xA9, 0xD6, 0xBC, 0x04, + 0xD7, 0xAA, 0xD6, 0xBC, 0x04, 0xD7, 0x95, 0xD6, + 0xB9, 0x04, 0xD7, 0x91, 0xD6, 0xBF, 0x04, 0xD7, + // Bytes 31c0 - 31ff + 0x9B, 0xD6, 0xBF, 0x04, 0xD7, 0xA4, 0xD6, 0xBF, + 0x04, 0xD7, 0x90, 0xD7, 0x9C, 0x02, 0xD9, 0xB1, + 0x02, 0xD9, 0xBB, 0x02, 0xD9, 0xBE, 0x02, 0xDA, + 0x80, 0x02, 0xD9, 0xBA, 0x02, 0xD9, 0xBF, 0x02, + 0xD9, 0xB9, 0x02, 0xDA, 0xA4, 0x02, 0xDA, 0xA6, + 0x02, 0xDA, 0x84, 0x02, 0xDA, 0x83, 0x02, 0xDA, + 0x86, 0x02, 0xDA, 0x87, 0x02, 0xDA, 0x8D, 0x02, + 0xDA, 0x8C, 0x02, 0xDA, 0x8E, 0x02, 0xDA, 0x88, + // Bytes 3200 - 323f + 0x02, 0xDA, 0x98, 0x02, 0xDA, 0x91, 0x02, 0xDA, + 0xA9, 0x02, 0xDA, 0xAF, 0x02, 0xDA, 0xB3, 0x02, + 0xDA, 0xB1, 0x02, 0xDA, 0xBA, 0x02, 0xDA, 0xBB, + 0x02, 0xDB, 0x81, 0x02, 0xDA, 0xBE, 0x02, 0xDB, + 0x92, 0x02, 0xDA, 0xAD, 0x02, 0xDB, 0x87, 0x02, + 0xDB, 0x86, 0x02, 0xDB, 0x88, 0x02, 0xDB, 0x8B, + 0x02, 0xDB, 0x85, 0x02, 0xDB, 0x89, 0x02, 0xDB, + 0x90, 0x02, 0xD9, 0x89, 0x06, 0xD9, 0x8A, 0xD9, + // Bytes 3240 - 327f + 0x94, 0xD8, 0xA7, 0x06, 0xD9, 0x8A, 0xD9, 0x94, + 0xDB, 0x95, 0x06, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, + 0x88, 0x06, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x87, + 0x06, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x86, 0x06, + 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x88, 0x06, 0xD9, + 0x8A, 0xD9, 0x94, 0xDB, 0x90, 0x06, 0xD9, 0x8A, + 0xD9, 0x94, 0xD9, 0x89, 0x02, 0xDB, 0x8C, 0x06, + 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xAC, 0x06, 0xD9, + // Bytes 3280 - 32bf + 0x8A, 0xD9, 0x94, 0xD8, 0xAD, 0x06, 0xD9, 0x8A, + 0xD9, 0x94, 0xD9, 0x85, 0x06, 0xD9, 0x8A, 0xD9, + 0x94, 0xD9, 0x8A, 0x04, 0xD8, 0xA8, 0xD8, 0xAC, + 0x04, 0xD8, 0xA8, 0xD8, 0xAD, 0x04, 0xD8, 0xA8, + 0xD8, 0xAE, 0x04, 0xD8, 0xA8, 0xD9, 0x85, 0x04, + 0xD8, 0xA8, 0xD9, 0x89, 0x04, 0xD8, 0xA8, 0xD9, + 0x8A, 0x04, 0xD8, 0xAA, 0xD8, 0xAC, 0x04, 0xD8, + 0xAA, 0xD8, 0xAD, 0x04, 0xD8, 0xAA, 0xD8, 0xAE, + // Bytes 32c0 - 32ff + 0x04, 0xD8, 0xAA, 0xD9, 0x85, 0x04, 0xD8, 0xAA, + 0xD9, 0x89, 0x04, 0xD8, 0xAA, 0xD9, 0x8A, 0x04, + 0xD8, 0xAB, 0xD8, 0xAC, 0x04, 0xD8, 0xAB, 0xD9, + 0x85, 0x04, 0xD8, 0xAB, 0xD9, 0x89, 0x04, 0xD8, + 0xAB, 0xD9, 0x8A, 0x04, 0xD8, 0xAC, 0xD8, 0xAD, + 0x04, 0xD8, 0xAC, 0xD9, 0x85, 0x04, 0xD8, 0xAD, + 0xD8, 0xAC, 0x04, 0xD8, 0xAD, 0xD9, 0x85, 0x04, + 0xD8, 0xAE, 0xD8, 0xAC, 0x04, 0xD8, 0xAE, 0xD8, + // Bytes 3300 - 333f + 0xAD, 0x04, 0xD8, 0xAE, 0xD9, 0x85, 0x04, 0xD8, + 0xB3, 0xD8, 0xAC, 0x04, 0xD8, 0xB3, 0xD8, 0xAD, + 0x04, 0xD8, 0xB3, 0xD8, 0xAE, 0x04, 0xD8, 0xB3, + 0xD9, 0x85, 0x04, 0xD8, 0xB5, 0xD8, 0xAD, 0x04, + 0xD8, 0xB5, 0xD9, 0x85, 0x04, 0xD8, 0xB6, 0xD8, + 0xAC, 0x04, 0xD8, 0xB6, 0xD8, 0xAD, 0x04, 0xD8, + 0xB6, 0xD8, 0xAE, 0x04, 0xD8, 0xB6, 0xD9, 0x85, + 0x04, 0xD8, 0xB7, 0xD8, 0xAD, 0x04, 0xD8, 0xB7, + // Bytes 3340 - 337f + 0xD9, 0x85, 0x04, 0xD8, 0xB8, 0xD9, 0x85, 0x04, + 0xD8, 0xB9, 0xD8, 0xAC, 0x04, 0xD8, 0xB9, 0xD9, + 0x85, 0x04, 0xD8, 0xBA, 0xD8, 0xAC, 0x04, 0xD8, + 0xBA, 0xD9, 0x85, 0x04, 0xD9, 0x81, 0xD8, 0xAC, + 0x04, 0xD9, 0x81, 0xD8, 0xAD, 0x04, 0xD9, 0x81, + 0xD8, 0xAE, 0x04, 0xD9, 0x81, 0xD9, 0x85, 0x04, + 0xD9, 0x81, 0xD9, 0x89, 0x04, 0xD9, 0x81, 0xD9, + 0x8A, 0x04, 0xD9, 0x82, 0xD8, 0xAD, 0x04, 0xD9, + // Bytes 3380 - 33bf + 0x82, 0xD9, 0x85, 0x04, 0xD9, 0x82, 0xD9, 0x89, + 0x04, 0xD9, 0x82, 0xD9, 0x8A, 0x04, 0xD9, 0x83, + 0xD8, 0xA7, 0x04, 0xD9, 0x83, 0xD8, 0xAC, 0x04, + 0xD9, 0x83, 0xD8, 0xAD, 0x04, 0xD9, 0x83, 0xD8, + 0xAE, 0x04, 0xD9, 0x83, 0xD9, 0x84, 0x04, 0xD9, + 0x83, 0xD9, 0x85, 0x04, 0xD9, 0x83, 0xD9, 0x89, + 0x04, 0xD9, 0x83, 0xD9, 0x8A, 0x04, 0xD9, 0x84, + 0xD8, 0xAC, 0x04, 0xD9, 0x84, 0xD8, 0xAD, 0x04, + // Bytes 33c0 - 33ff + 0xD9, 0x84, 0xD8, 0xAE, 0x04, 0xD9, 0x84, 0xD9, + 0x85, 0x04, 0xD9, 0x84, 0xD9, 0x89, 0x04, 0xD9, + 0x84, 0xD9, 0x8A, 0x04, 0xD9, 0x85, 0xD8, 0xAC, + 0x04, 0xD9, 0x85, 0xD8, 0xAD, 0x04, 0xD9, 0x85, + 0xD8, 0xAE, 0x04, 0xD9, 0x85, 0xD9, 0x85, 0x04, + 0xD9, 0x85, 0xD9, 0x89, 0x04, 0xD9, 0x85, 0xD9, + 0x8A, 0x04, 0xD9, 0x86, 0xD8, 0xAC, 0x04, 0xD9, + 0x86, 0xD8, 0xAD, 0x04, 0xD9, 0x86, 0xD8, 0xAE, + // Bytes 3400 - 343f + 0x04, 0xD9, 0x86, 0xD9, 0x85, 0x04, 0xD9, 0x86, + 0xD9, 0x89, 0x04, 0xD9, 0x86, 0xD9, 0x8A, 0x04, + 0xD9, 0x87, 0xD8, 0xAC, 0x04, 0xD9, 0x87, 0xD9, + 0x85, 0x04, 0xD9, 0x87, 0xD9, 0x89, 0x04, 0xD9, + 0x87, 0xD9, 0x8A, 0x04, 0xD9, 0x8A, 0xD8, 0xAC, + 0x04, 0xD9, 0x8A, 0xD8, 0xAD, 0x04, 0xD9, 0x8A, + 0xD8, 0xAE, 0x04, 0xD9, 0x8A, 0xD9, 0x85, 0x04, + 0xD9, 0x8A, 0xD9, 0x89, 0x04, 0xD9, 0x8A, 0xD9, + // Bytes 3440 - 347f + 0x8A, 0x04, 0xD8, 0xB0, 0xD9, 0xB0, 0x04, 0xD8, + 0xB1, 0xD9, 0xB0, 0x04, 0xD9, 0x89, 0xD9, 0xB0, + 0x05, 0x20, 0xD9, 0x8C, 0xD9, 0x91, 0x05, 0x20, + 0xD9, 0x8D, 0xD9, 0x91, 0x05, 0x20, 0xD9, 0x8E, + 0xD9, 0x91, 0x05, 0x20, 0xD9, 0x8F, 0xD9, 0x91, + 0x05, 0x20, 0xD9, 0x90, 0xD9, 0x91, 0x05, 0x20, + 0xD9, 0x91, 0xD9, 0xB0, 0x06, 0xD9, 0x8A, 0xD9, + 0x94, 0xD8, 0xB1, 0x06, 0xD9, 0x8A, 0xD9, 0x94, + // Bytes 3480 - 34bf + 0xD8, 0xB2, 0x06, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, + 0x86, 0x04, 0xD8, 0xA8, 0xD8, 0xB1, 0x04, 0xD8, + 0xA8, 0xD8, 0xB2, 0x04, 0xD8, 0xA8, 0xD9, 0x86, + 0x04, 0xD8, 0xAA, 0xD8, 0xB1, 0x04, 0xD8, 0xAA, + 0xD8, 0xB2, 0x04, 0xD8, 0xAA, 0xD9, 0x86, 0x04, + 0xD8, 0xAB, 0xD8, 0xB1, 0x04, 0xD8, 0xAB, 0xD8, + 0xB2, 0x04, 0xD8, 0xAB, 0xD9, 0x86, 0x04, 0xD9, + 0x85, 0xD8, 0xA7, 0x04, 0xD9, 0x86, 0xD8, 0xB1, + // Bytes 34c0 - 34ff + 0x04, 0xD9, 0x86, 0xD8, 0xB2, 0x04, 0xD9, 0x86, + 0xD9, 0x86, 0x04, 0xD9, 0x8A, 0xD8, 0xB1, 0x04, + 0xD9, 0x8A, 0xD8, 0xB2, 0x04, 0xD9, 0x8A, 0xD9, + 0x86, 0x06, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xAE, + 0x06, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x87, 0x04, + 0xD8, 0xA8, 0xD9, 0x87, 0x04, 0xD8, 0xAA, 0xD9, + 0x87, 0x04, 0xD8, 0xB5, 0xD8, 0xAE, 0x04, 0xD9, + 0x84, 0xD9, 0x87, 0x04, 0xD9, 0x86, 0xD9, 0x87, + // Bytes 3500 - 353f + 0x04, 0xD9, 0x87, 0xD9, 0xB0, 0x04, 0xD9, 0x8A, + 0xD9, 0x87, 0x04, 0xD8, 0xAB, 0xD9, 0x87, 0x04, + 0xD8, 0xB3, 0xD9, 0x87, 0x04, 0xD8, 0xB4, 0xD9, + 0x85, 0x04, 0xD8, 0xB4, 0xD9, 0x87, 0x06, 0xD9, + 0x80, 0xD9, 0x8E, 0xD9, 0x91, 0x06, 0xD9, 0x80, + 0xD9, 0x8F, 0xD9, 0x91, 0x06, 0xD9, 0x80, 0xD9, + 0x90, 0xD9, 0x91, 0x04, 0xD8, 0xB7, 0xD9, 0x89, + 0x04, 0xD8, 0xB7, 0xD9, 0x8A, 0x04, 0xD8, 0xB9, + // Bytes 3540 - 357f + 0xD9, 0x89, 0x04, 0xD8, 0xB9, 0xD9, 0x8A, 0x04, + 0xD8, 0xBA, 0xD9, 0x89, 0x04, 0xD8, 0xBA, 0xD9, + 0x8A, 0x04, 0xD8, 0xB3, 0xD9, 0x89, 0x04, 0xD8, + 0xB3, 0xD9, 0x8A, 0x04, 0xD8, 0xB4, 0xD9, 0x89, + 0x04, 0xD8, 0xB4, 0xD9, 0x8A, 0x04, 0xD8, 0xAD, + 0xD9, 0x89, 0x04, 0xD8, 0xAD, 0xD9, 0x8A, 0x04, + 0xD8, 0xAC, 0xD9, 0x89, 0x04, 0xD8, 0xAC, 0xD9, + 0x8A, 0x04, 0xD8, 0xAE, 0xD9, 0x89, 0x04, 0xD8, + // Bytes 3580 - 35bf + 0xAE, 0xD9, 0x8A, 0x04, 0xD8, 0xB5, 0xD9, 0x89, + 0x04, 0xD8, 0xB5, 0xD9, 0x8A, 0x04, 0xD8, 0xB6, + 0xD9, 0x89, 0x04, 0xD8, 0xB6, 0xD9, 0x8A, 0x04, + 0xD8, 0xB4, 0xD8, 0xAC, 0x04, 0xD8, 0xB4, 0xD8, + 0xAD, 0x04, 0xD8, 0xB4, 0xD8, 0xAE, 0x04, 0xD8, + 0xB4, 0xD8, 0xB1, 0x04, 0xD8, 0xB3, 0xD8, 0xB1, + 0x04, 0xD8, 0xB5, 0xD8, 0xB1, 0x04, 0xD8, 0xB6, + 0xD8, 0xB1, 0x04, 0xD8, 0xA7, 0xD9, 0x8B, 0x06, + // Bytes 35c0 - 35ff + 0xD8, 0xAA, 0xD8, 0xAC, 0xD9, 0x85, 0x06, 0xD8, + 0xAA, 0xD8, 0xAD, 0xD8, 0xAC, 0x06, 0xD8, 0xAA, + 0xD8, 0xAD, 0xD9, 0x85, 0x06, 0xD8, 0xAA, 0xD8, + 0xAE, 0xD9, 0x85, 0x06, 0xD8, 0xAA, 0xD9, 0x85, + 0xD8, 0xAC, 0x06, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, + 0xAD, 0x06, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAE, + 0x06, 0xD8, 0xAC, 0xD9, 0x85, 0xD8, 0xAD, 0x06, + 0xD8, 0xAD, 0xD9, 0x85, 0xD9, 0x8A, 0x06, 0xD8, + // Bytes 3600 - 363f + 0xAD, 0xD9, 0x85, 0xD9, 0x89, 0x06, 0xD8, 0xB3, + 0xD8, 0xAD, 0xD8, 0xAC, 0x06, 0xD8, 0xB3, 0xD8, + 0xAC, 0xD8, 0xAD, 0x06, 0xD8, 0xB3, 0xD8, 0xAC, + 0xD9, 0x89, 0x06, 0xD8, 0xB3, 0xD9, 0x85, 0xD8, + 0xAD, 0x06, 0xD8, 0xB3, 0xD9, 0x85, 0xD8, 0xAC, + 0x06, 0xD8, 0xB3, 0xD9, 0x85, 0xD9, 0x85, 0x06, + 0xD8, 0xB5, 0xD8, 0xAD, 0xD8, 0xAD, 0x06, 0xD8, + 0xB5, 0xD9, 0x85, 0xD9, 0x85, 0x06, 0xD8, 0xB4, + // Bytes 3640 - 367f + 0xD8, 0xAD, 0xD9, 0x85, 0x06, 0xD8, 0xB4, 0xD8, + 0xAC, 0xD9, 0x8A, 0x06, 0xD8, 0xB4, 0xD9, 0x85, + 0xD8, 0xAE, 0x06, 0xD8, 0xB4, 0xD9, 0x85, 0xD9, + 0x85, 0x06, 0xD8, 0xB6, 0xD8, 0xAD, 0xD9, 0x89, + 0x06, 0xD8, 0xB6, 0xD8, 0xAE, 0xD9, 0x85, 0x06, + 0xD8, 0xB7, 0xD9, 0x85, 0xD8, 0xAD, 0x06, 0xD8, + 0xB7, 0xD9, 0x85, 0xD9, 0x85, 0x06, 0xD8, 0xB7, + 0xD9, 0x85, 0xD9, 0x8A, 0x06, 0xD8, 0xB9, 0xD8, + // Bytes 3680 - 36bf + 0xAC, 0xD9, 0x85, 0x06, 0xD8, 0xB9, 0xD9, 0x85, + 0xD9, 0x85, 0x06, 0xD8, 0xB9, 0xD9, 0x85, 0xD9, + 0x89, 0x06, 0xD8, 0xBA, 0xD9, 0x85, 0xD9, 0x85, + 0x06, 0xD8, 0xBA, 0xD9, 0x85, 0xD9, 0x8A, 0x06, + 0xD8, 0xBA, 0xD9, 0x85, 0xD9, 0x89, 0x06, 0xD9, + 0x81, 0xD8, 0xAE, 0xD9, 0x85, 0x06, 0xD9, 0x82, + 0xD9, 0x85, 0xD8, 0xAD, 0x06, 0xD9, 0x82, 0xD9, + 0x85, 0xD9, 0x85, 0x06, 0xD9, 0x84, 0xD8, 0xAD, + // Bytes 36c0 - 36ff + 0xD9, 0x85, 0x06, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, + 0x8A, 0x06, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, 0x89, + 0x06, 0xD9, 0x84, 0xD8, 0xAC, 0xD8, 0xAC, 0x06, + 0xD9, 0x84, 0xD8, 0xAE, 0xD9, 0x85, 0x06, 0xD9, + 0x84, 0xD9, 0x85, 0xD8, 0xAD, 0x06, 0xD9, 0x85, + 0xD8, 0xAD, 0xD8, 0xAC, 0x06, 0xD9, 0x85, 0xD8, + 0xAD, 0xD9, 0x85, 0x06, 0xD9, 0x85, 0xD8, 0xAD, + 0xD9, 0x8A, 0x06, 0xD9, 0x85, 0xD8, 0xAC, 0xD8, + // Bytes 3700 - 373f + 0xAD, 0x06, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, 0x85, + 0x06, 0xD9, 0x85, 0xD8, 0xAE, 0xD8, 0xAC, 0x06, + 0xD9, 0x85, 0xD8, 0xAE, 0xD9, 0x85, 0x06, 0xD9, + 0x85, 0xD8, 0xAC, 0xD8, 0xAE, 0x06, 0xD9, 0x87, + 0xD9, 0x85, 0xD8, 0xAC, 0x06, 0xD9, 0x87, 0xD9, + 0x85, 0xD9, 0x85, 0x06, 0xD9, 0x86, 0xD8, 0xAD, + 0xD9, 0x85, 0x06, 0xD9, 0x86, 0xD8, 0xAD, 0xD9, + 0x89, 0x06, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x85, + // Bytes 3740 - 377f + 0x06, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x89, 0x06, + 0xD9, 0x86, 0xD9, 0x85, 0xD9, 0x8A, 0x06, 0xD9, + 0x86, 0xD9, 0x85, 0xD9, 0x89, 0x06, 0xD9, 0x8A, + 0xD9, 0x85, 0xD9, 0x85, 0x06, 0xD8, 0xA8, 0xD8, + 0xAE, 0xD9, 0x8A, 0x06, 0xD8, 0xAA, 0xD8, 0xAC, + 0xD9, 0x8A, 0x06, 0xD8, 0xAA, 0xD8, 0xAC, 0xD9, + 0x89, 0x06, 0xD8, 0xAA, 0xD8, 0xAE, 0xD9, 0x8A, + 0x06, 0xD8, 0xAA, 0xD8, 0xAE, 0xD9, 0x89, 0x06, + // Bytes 3780 - 37bf + 0xD8, 0xAA, 0xD9, 0x85, 0xD9, 0x8A, 0x06, 0xD8, + 0xAA, 0xD9, 0x85, 0xD9, 0x89, 0x06, 0xD8, 0xAC, + 0xD9, 0x85, 0xD9, 0x8A, 0x06, 0xD8, 0xAC, 0xD8, + 0xAD, 0xD9, 0x89, 0x06, 0xD8, 0xAC, 0xD9, 0x85, + 0xD9, 0x89, 0x06, 0xD8, 0xB3, 0xD8, 0xAE, 0xD9, + 0x89, 0x06, 0xD8, 0xB5, 0xD8, 0xAD, 0xD9, 0x8A, + 0x06, 0xD8, 0xB4, 0xD8, 0xAD, 0xD9, 0x8A, 0x06, + 0xD8, 0xB6, 0xD8, 0xAD, 0xD9, 0x8A, 0x06, 0xD9, + // Bytes 37c0 - 37ff + 0x84, 0xD8, 0xAC, 0xD9, 0x8A, 0x06, 0xD9, 0x84, + 0xD9, 0x85, 0xD9, 0x8A, 0x06, 0xD9, 0x8A, 0xD8, + 0xAD, 0xD9, 0x8A, 0x06, 0xD9, 0x8A, 0xD8, 0xAC, + 0xD9, 0x8A, 0x06, 0xD9, 0x8A, 0xD9, 0x85, 0xD9, + 0x8A, 0x06, 0xD9, 0x85, 0xD9, 0x85, 0xD9, 0x8A, + 0x06, 0xD9, 0x82, 0xD9, 0x85, 0xD9, 0x8A, 0x06, + 0xD9, 0x86, 0xD8, 0xAD, 0xD9, 0x8A, 0x06, 0xD8, + 0xB9, 0xD9, 0x85, 0xD9, 0x8A, 0x06, 0xD9, 0x83, + // Bytes 3800 - 383f + 0xD9, 0x85, 0xD9, 0x8A, 0x06, 0xD9, 0x86, 0xD8, + 0xAC, 0xD8, 0xAD, 0x06, 0xD9, 0x85, 0xD8, 0xAE, + 0xD9, 0x8A, 0x06, 0xD9, 0x84, 0xD8, 0xAC, 0xD9, + 0x85, 0x06, 0xD9, 0x83, 0xD9, 0x85, 0xD9, 0x85, + 0x06, 0xD8, 0xAC, 0xD8, 0xAD, 0xD9, 0x8A, 0x06, + 0xD8, 0xAD, 0xD8, 0xAC, 0xD9, 0x8A, 0x06, 0xD9, + 0x85, 0xD8, 0xAC, 0xD9, 0x8A, 0x06, 0xD9, 0x81, + 0xD9, 0x85, 0xD9, 0x8A, 0x06, 0xD8, 0xA8, 0xD8, + // Bytes 3840 - 387f + 0xAD, 0xD9, 0x8A, 0x06, 0xD8, 0xB3, 0xD8, 0xAE, + 0xD9, 0x8A, 0x06, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, + 0x8A, 0x06, 0xD8, 0xB5, 0xD9, 0x84, 0xDB, 0x92, + 0x06, 0xD9, 0x82, 0xD9, 0x84, 0xDB, 0x92, 0x08, + 0xD8, 0xA7, 0xD9, 0x84, 0xD9, 0x84, 0xD9, 0x87, + 0x08, 0xD8, 0xA7, 0xD9, 0x83, 0xD8, 0xA8, 0xD8, + 0xB1, 0x08, 0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x85, + 0xD8, 0xAF, 0x08, 0xD8, 0xB5, 0xD9, 0x84, 0xD8, + // Bytes 3880 - 38bf + 0xB9, 0xD9, 0x85, 0x08, 0xD8, 0xB1, 0xD8, 0xB3, + 0xD9, 0x88, 0xD9, 0x84, 0x08, 0xD8, 0xB9, 0xD9, + 0x84, 0xD9, 0x8A, 0xD9, 0x87, 0x08, 0xD9, 0x88, + 0xD8, 0xB3, 0xD9, 0x84, 0xD9, 0x85, 0x06, 0xD8, + 0xB5, 0xD9, 0x84, 0xD9, 0x89, 0x21, 0xD8, 0xB5, + 0xD9, 0x84, 0xD9, 0x89, 0x20, 0xD8, 0xA7, 0xD9, + 0x84, 0xD9, 0x84, 0xD9, 0x87, 0x20, 0xD8, 0xB9, + 0xD9, 0x84, 0xD9, 0x8A, 0xD9, 0x87, 0x20, 0xD9, + // Bytes 38c0 - 38ff + 0x88, 0xD8, 0xB3, 0xD9, 0x84, 0xD9, 0x85, 0x0F, + 0xD8, 0xAC, 0xD9, 0x84, 0x20, 0xD8, 0xAC, 0xD9, + 0x84, 0xD8, 0xA7, 0xD9, 0x84, 0xD9, 0x87, 0x08, + 0xD8, 0xB1, 0xDB, 0x8C, 0xD8, 0xA7, 0xD9, 0x84, + 0x01, 0x2C, 0x03, 0xE3, 0x80, 0x81, 0x03, 0xE3, + 0x80, 0x82, 0x01, 0x3A, 0x01, 0x21, 0x01, 0x3F, + 0x03, 0xE3, 0x80, 0x96, 0x03, 0xE3, 0x80, 0x97, + 0x03, 0xE2, 0x80, 0x94, 0x03, 0xE2, 0x80, 0x93, + // Bytes 3900 - 393f + 0x01, 0x5F, 0x01, 0x7B, 0x01, 0x7D, 0x03, 0xE3, + 0x80, 0x94, 0x03, 0xE3, 0x80, 0x95, 0x03, 0xE3, + 0x80, 0x90, 0x03, 0xE3, 0x80, 0x91, 0x03, 0xE3, + 0x80, 0x8A, 0x03, 0xE3, 0x80, 0x8B, 0x03, 0xE3, + 0x80, 0x8C, 0x03, 0xE3, 0x80, 0x8D, 0x03, 0xE3, + 0x80, 0x8E, 0x03, 0xE3, 0x80, 0x8F, 0x01, 0x5B, + 0x01, 0x5D, 0x01, 0x23, 0x01, 0x26, 0x01, 0x2A, + 0x01, 0x2D, 0x01, 0x3C, 0x01, 0x3E, 0x01, 0x5C, + // Bytes 3940 - 397f + 0x01, 0x24, 0x01, 0x25, 0x01, 0x40, 0x03, 0x20, + 0xD9, 0x8B, 0x04, 0xD9, 0x80, 0xD9, 0x8B, 0x03, + 0x20, 0xD9, 0x8C, 0x03, 0x20, 0xD9, 0x8D, 0x03, + 0x20, 0xD9, 0x8E, 0x04, 0xD9, 0x80, 0xD9, 0x8E, + 0x03, 0x20, 0xD9, 0x8F, 0x04, 0xD9, 0x80, 0xD9, + 0x8F, 0x03, 0x20, 0xD9, 0x90, 0x04, 0xD9, 0x80, + 0xD9, 0x90, 0x03, 0x20, 0xD9, 0x91, 0x04, 0xD9, + 0x80, 0xD9, 0x91, 0x03, 0x20, 0xD9, 0x92, 0x04, + // Bytes 3980 - 39bf + 0xD9, 0x80, 0xD9, 0x92, 0x02, 0xD8, 0xA1, 0x02, + 0xD8, 0xA7, 0x02, 0xD8, 0xA8, 0x02, 0xD8, 0xA9, + 0x02, 0xD8, 0xAA, 0x02, 0xD8, 0xAB, 0x02, 0xD8, + 0xAC, 0x02, 0xD8, 0xAD, 0x02, 0xD8, 0xAE, 0x02, + 0xD8, 0xAF, 0x02, 0xD8, 0xB0, 0x02, 0xD8, 0xB1, + 0x02, 0xD8, 0xB2, 0x02, 0xD8, 0xB3, 0x02, 0xD8, + 0xB4, 0x02, 0xD8, 0xB5, 0x02, 0xD8, 0xB6, 0x02, + 0xD8, 0xB7, 0x02, 0xD8, 0xB8, 0x02, 0xD8, 0xB9, + // Bytes 39c0 - 39ff + 0x02, 0xD8, 0xBA, 0x02, 0xD9, 0x81, 0x02, 0xD9, + 0x82, 0x02, 0xD9, 0x83, 0x02, 0xD9, 0x84, 0x02, + 0xD9, 0x85, 0x02, 0xD9, 0x86, 0x02, 0xD9, 0x87, + 0x02, 0xD9, 0x88, 0x02, 0xD9, 0x8A, 0x06, 0xD9, + 0x84, 0xD8, 0xA7, 0xD9, 0x93, 0x06, 0xD9, 0x84, + 0xD8, 0xA7, 0xD9, 0x94, 0x06, 0xD9, 0x84, 0xD8, + 0xA7, 0xD9, 0x95, 0x04, 0xD9, 0x84, 0xD8, 0xA7, + 0x01, 0x22, 0x01, 0x27, 0x01, 0x2F, 0x01, 0x5E, + // Bytes 3a00 - 3a3f + 0x01, 0x7C, 0x01, 0x7E, 0x03, 0xE2, 0xA6, 0x85, + 0x03, 0xE2, 0xA6, 0x86, 0x03, 0xE3, 0x83, 0xBB, + 0x03, 0xE3, 0x82, 0xA1, 0x03, 0xE3, 0x82, 0xA3, + 0x03, 0xE3, 0x82, 0xA5, 0x03, 0xE3, 0x82, 0xA7, + 0x03, 0xE3, 0x82, 0xA9, 0x03, 0xE3, 0x83, 0xA3, + 0x03, 0xE3, 0x83, 0xA5, 0x03, 0xE3, 0x83, 0xA7, + 0x03, 0xE3, 0x83, 0x83, 0x03, 0xE3, 0x83, 0xBC, + 0x03, 0xE3, 0x83, 0xB3, 0x03, 0xE3, 0x82, 0x99, + // Bytes 3a40 - 3a7f + 0x03, 0xE3, 0x82, 0x9A, 0x02, 0xC2, 0xA2, 0x02, + 0xC2, 0xA3, 0x02, 0xC2, 0xAC, 0x02, 0xC2, 0xA6, + 0x02, 0xC2, 0xA5, 0x03, 0xE2, 0x82, 0xA9, 0x03, + 0xE2, 0x94, 0x82, 0x03, 0xE2, 0x86, 0x90, 0x03, + 0xE2, 0x86, 0x91, 0x03, 0xE2, 0x86, 0x92, 0x03, + 0xE2, 0x86, 0x93, 0x03, 0xE2, 0x96, 0xA0, 0x03, + 0xE2, 0x97, 0x8B, 0x08, 0xF0, 0x91, 0x82, 0x99, + 0xF0, 0x91, 0x82, 0xBA, 0x08, 0xF0, 0x91, 0x82, + // Bytes 3a80 - 3abf + 0x9B, 0xF0, 0x91, 0x82, 0xBA, 0x08, 0xF0, 0x91, + 0x82, 0xA5, 0xF0, 0x91, 0x82, 0xBA, 0x08, 0xF0, + 0x9D, 0x85, 0x97, 0xF0, 0x9D, 0x85, 0xA5, 0x08, + 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, + 0x0C, 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, + 0xA5, 0xF0, 0x9D, 0x85, 0xAE, 0x0C, 0xF0, 0x9D, + 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, + 0x85, 0xAF, 0x0C, 0xF0, 0x9D, 0x85, 0x98, 0xF0, + // Bytes 3ac0 - 3aff + 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xB0, 0x0C, + 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, + 0xF0, 0x9D, 0x85, 0xB1, 0x0C, 0xF0, 0x9D, 0x85, + 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, + 0xB2, 0x08, 0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D, + 0x85, 0xA5, 0x08, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, + 0x9D, 0x85, 0xA5, 0x0C, 0xF0, 0x9D, 0x86, 0xB9, + 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAE, + // Bytes 3b00 - 3b3f + 0x0C, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, 0x9D, 0x85, + 0xA5, 0xF0, 0x9D, 0x85, 0xAE, 0x0C, 0xF0, 0x9D, + 0x86, 0xB9, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, + 0x85, 0xAF, 0x0C, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, + 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAF, 0x02, + 0xC4, 0xB1, 0x02, 0xC8, 0xB7, 0x02, 0xCE, 0x91, + 0x02, 0xCE, 0x92, 0x02, 0xCE, 0x94, 0x02, 0xCE, + 0x95, 0x02, 0xCE, 0x96, 0x02, 0xCE, 0x97, 0x02, + // Bytes 3b40 - 3b7f + 0xCE, 0x99, 0x02, 0xCE, 0x9A, 0x02, 0xCE, 0x9B, + 0x02, 0xCE, 0x9C, 0x02, 0xCE, 0x9D, 0x02, 0xCE, + 0x9E, 0x02, 0xCE, 0x9F, 0x02, 0xCE, 0xA1, 0x02, + 0xCE, 0xA4, 0x02, 0xCE, 0xA6, 0x02, 0xCE, 0xA7, + 0x02, 0xCE, 0xA8, 0x03, 0xE2, 0x88, 0x87, 0x02, + 0xCE, 0xB1, 0x02, 0xCE, 0xB6, 0x02, 0xCE, 0xB7, + 0x02, 0xCE, 0xBB, 0x02, 0xCE, 0xBD, 0x02, 0xCE, + 0xBE, 0x02, 0xCE, 0xBF, 0x02, 0xCF, 0x83, 0x02, + // Bytes 3b80 - 3bbf + 0xCF, 0x84, 0x02, 0xCF, 0x85, 0x02, 0xCF, 0x88, + 0x02, 0xCF, 0x89, 0x03, 0xE2, 0x88, 0x82, 0x02, + 0xCF, 0x9C, 0x02, 0xCF, 0x9D, 0x02, 0x30, 0x2E, + 0x02, 0x30, 0x2C, 0x02, 0x31, 0x2C, 0x02, 0x32, + 0x2C, 0x02, 0x33, 0x2C, 0x02, 0x34, 0x2C, 0x02, + 0x35, 0x2C, 0x02, 0x36, 0x2C, 0x02, 0x37, 0x2C, + 0x02, 0x38, 0x2C, 0x02, 0x39, 0x2C, 0x03, 0x28, + 0x41, 0x29, 0x03, 0x28, 0x42, 0x29, 0x03, 0x28, + // Bytes 3bc0 - 3bff + 0x43, 0x29, 0x03, 0x28, 0x44, 0x29, 0x03, 0x28, + 0x45, 0x29, 0x03, 0x28, 0x46, 0x29, 0x03, 0x28, + 0x47, 0x29, 0x03, 0x28, 0x48, 0x29, 0x03, 0x28, + 0x49, 0x29, 0x03, 0x28, 0x4A, 0x29, 0x03, 0x28, + 0x4B, 0x29, 0x03, 0x28, 0x4C, 0x29, 0x03, 0x28, + 0x4D, 0x29, 0x03, 0x28, 0x4E, 0x29, 0x03, 0x28, + 0x4F, 0x29, 0x03, 0x28, 0x50, 0x29, 0x03, 0x28, + 0x51, 0x29, 0x03, 0x28, 0x52, 0x29, 0x03, 0x28, + // Bytes 3c00 - 3c3f + 0x53, 0x29, 0x03, 0x28, 0x54, 0x29, 0x03, 0x28, + 0x55, 0x29, 0x03, 0x28, 0x56, 0x29, 0x03, 0x28, + 0x57, 0x29, 0x03, 0x28, 0x58, 0x29, 0x03, 0x28, + 0x59, 0x29, 0x03, 0x28, 0x5A, 0x29, 0x07, 0xE3, + 0x80, 0x94, 0x53, 0xE3, 0x80, 0x95, 0x02, 0x43, + 0x44, 0x02, 0x57, 0x5A, 0x02, 0x48, 0x56, 0x02, + 0x53, 0x44, 0x02, 0x53, 0x53, 0x03, 0x50, 0x50, + 0x56, 0x02, 0x57, 0x43, 0x02, 0x44, 0x4A, 0x06, + // Bytes 3c40 - 3c7f + 0xE3, 0x81, 0xBB, 0xE3, 0x81, 0x8B, 0x06, 0xE3, + 0x82, 0xB3, 0xE3, 0x82, 0xB3, 0x03, 0xE5, 0xAD, + 0x97, 0x03, 0xE5, 0x8F, 0x8C, 0x03, 0xE5, 0xA4, + 0x9A, 0x03, 0xE8, 0xA7, 0xA3, 0x03, 0xE4, 0xBA, + 0xA4, 0x03, 0xE6, 0x98, 0xA0, 0x03, 0xE7, 0x84, + 0xA1, 0x03, 0xE5, 0x89, 0x8D, 0x03, 0xE5, 0xBE, + 0x8C, 0x03, 0xE5, 0x86, 0x8D, 0x03, 0xE6, 0x96, + 0xB0, 0x03, 0xE5, 0x88, 0x9D, 0x03, 0xE7, 0xB5, + // Bytes 3c80 - 3cbf + 0x82, 0x03, 0xE8, 0xB2, 0xA9, 0x03, 0xE5, 0xA3, + 0xB0, 0x03, 0xE5, 0x90, 0xB9, 0x03, 0xE6, 0xBC, + 0x94, 0x03, 0xE6, 0x8A, 0x95, 0x03, 0xE6, 0x8D, + 0x95, 0x03, 0xE9, 0x81, 0x8A, 0x03, 0xE6, 0x8C, + 0x87, 0x03, 0xE6, 0x89, 0x93, 0x03, 0xE7, 0xA6, + 0x81, 0x03, 0xE7, 0xA9, 0xBA, 0x03, 0xE5, 0x90, + 0x88, 0x03, 0xE6, 0xBA, 0x80, 0x03, 0xE7, 0x94, + 0xB3, 0x03, 0xE5, 0x89, 0xB2, 0x03, 0xE5, 0x96, + // Bytes 3cc0 - 3cff + 0xB6, 0x09, 0xE3, 0x80, 0x94, 0xE6, 0x9C, 0xAC, + 0xE3, 0x80, 0x95, 0x09, 0xE3, 0x80, 0x94, 0xE4, + 0xB8, 0x89, 0xE3, 0x80, 0x95, 0x09, 0xE3, 0x80, + 0x94, 0xE4, 0xBA, 0x8C, 0xE3, 0x80, 0x95, 0x09, + 0xE3, 0x80, 0x94, 0xE5, 0xAE, 0x89, 0xE3, 0x80, + 0x95, 0x09, 0xE3, 0x80, 0x94, 0xE7, 0x82, 0xB9, + 0xE3, 0x80, 0x95, 0x09, 0xE3, 0x80, 0x94, 0xE6, + 0x89, 0x93, 0xE3, 0x80, 0x95, 0x09, 0xE3, 0x80, + // Bytes 3d00 - 3d3f + 0x94, 0xE7, 0x9B, 0x97, 0xE3, 0x80, 0x95, 0x09, + 0xE3, 0x80, 0x94, 0xE5, 0x8B, 0x9D, 0xE3, 0x80, + 0x95, 0x09, 0xE3, 0x80, 0x94, 0xE6, 0x95, 0x97, + 0xE3, 0x80, 0x95, 0x03, 0xE5, 0xBE, 0x97, 0x03, + 0xE5, 0x8F, 0xAF, 0x03, 0xE4, 0xB8, 0xBD, 0x03, + 0xE4, 0xB8, 0xB8, 0x03, 0xE4, 0xB9, 0x81, 0x04, + 0xF0, 0xA0, 0x84, 0xA2, 0x03, 0xE4, 0xBD, 0xA0, + 0x03, 0xE4, 0xBE, 0xBB, 0x03, 0xE5, 0x80, 0x82, + // Bytes 3d40 - 3d7f + 0x03, 0xE5, 0x81, 0xBA, 0x03, 0xE5, 0x82, 0x99, + 0x03, 0xE5, 0x83, 0x8F, 0x03, 0xE3, 0x92, 0x9E, + 0x04, 0xF0, 0xA0, 0x98, 0xBA, 0x03, 0xE5, 0x85, + 0x94, 0x03, 0xE5, 0x85, 0xA4, 0x03, 0xE5, 0x85, + 0xB7, 0x04, 0xF0, 0xA0, 0x94, 0x9C, 0x03, 0xE3, + 0x92, 0xB9, 0x03, 0xE5, 0x85, 0xA7, 0x04, 0xF0, + 0xA0, 0x95, 0x8B, 0x03, 0xE5, 0x86, 0x97, 0x03, + 0xE5, 0x86, 0xA4, 0x03, 0xE4, 0xBB, 0x8C, 0x03, + // Bytes 3d80 - 3dbf + 0xE5, 0x86, 0xAC, 0x04, 0xF0, 0xA9, 0x87, 0x9F, + 0x03, 0xE5, 0x88, 0x83, 0x03, 0xE3, 0x93, 0x9F, + 0x03, 0xE5, 0x88, 0xBB, 0x03, 0xE5, 0x89, 0x86, + 0x03, 0xE5, 0x89, 0xB7, 0x03, 0xE3, 0x94, 0x95, + 0x03, 0xE5, 0x8C, 0x85, 0x03, 0xE5, 0x8C, 0x86, + 0x03, 0xE5, 0x8D, 0x89, 0x03, 0xE5, 0x8D, 0x9A, + 0x03, 0xE5, 0x8D, 0xB3, 0x03, 0xE5, 0x8D, 0xBD, + 0x03, 0xE5, 0x8D, 0xBF, 0x04, 0xF0, 0xA0, 0xA8, + // Bytes 3dc0 - 3dff + 0xAC, 0x03, 0xE7, 0x81, 0xB0, 0x03, 0xE5, 0x8F, + 0x8A, 0x03, 0xE5, 0x8F, 0x9F, 0x04, 0xF0, 0xA0, + 0xAD, 0xA3, 0x03, 0xE5, 0x8F, 0xAB, 0x03, 0xE5, + 0x8F, 0xB1, 0x03, 0xE5, 0x90, 0x86, 0x03, 0xE5, + 0x92, 0x9E, 0x03, 0xE5, 0x90, 0xB8, 0x03, 0xE5, + 0x91, 0x88, 0x03, 0xE5, 0x91, 0xA8, 0x03, 0xE5, + 0x92, 0xA2, 0x03, 0xE5, 0x93, 0xB6, 0x03, 0xE5, + 0x94, 0x90, 0x03, 0xE5, 0x95, 0x93, 0x03, 0xE5, + // Bytes 3e00 - 3e3f + 0x95, 0xA3, 0x03, 0xE5, 0x96, 0x84, 0x03, 0xE5, + 0x96, 0xAB, 0x03, 0xE5, 0x96, 0xB3, 0x03, 0xE5, + 0x97, 0x82, 0x03, 0xE5, 0x9C, 0x96, 0x03, 0xE5, + 0x9C, 0x97, 0x03, 0xE5, 0x99, 0x91, 0x03, 0xE5, + 0x99, 0xB4, 0x03, 0xE5, 0xA3, 0xAE, 0x03, 0xE5, + 0x9F, 0x8E, 0x03, 0xE5, 0x9F, 0xB4, 0x03, 0xE5, + 0xA0, 0x8D, 0x03, 0xE5, 0x9E, 0x8B, 0x03, 0xE5, + 0xA0, 0xB2, 0x03, 0xE5, 0xA0, 0xB1, 0x03, 0xE5, + // Bytes 3e40 - 3e7f + 0xA2, 0xAC, 0x04, 0xF0, 0xA1, 0x93, 0xA4, 0x03, + 0xE5, 0xA3, 0xB2, 0x03, 0xE5, 0xA3, 0xB7, 0x03, + 0xE5, 0xA4, 0x86, 0x03, 0xE5, 0xA4, 0xA2, 0x03, + 0xE5, 0xA5, 0xA2, 0x04, 0xF0, 0xA1, 0x9A, 0xA8, + 0x04, 0xF0, 0xA1, 0x9B, 0xAA, 0x03, 0xE5, 0xA7, + 0xAC, 0x03, 0xE5, 0xA8, 0x9B, 0x03, 0xE5, 0xA8, + 0xA7, 0x03, 0xE5, 0xA7, 0x98, 0x03, 0xE5, 0xA9, + 0xA6, 0x03, 0xE3, 0x9B, 0xAE, 0x03, 0xE3, 0x9B, + // Bytes 3e80 - 3ebf + 0xBC, 0x03, 0xE5, 0xAC, 0x88, 0x03, 0xE5, 0xAC, + 0xBE, 0x04, 0xF0, 0xA1, 0xA7, 0x88, 0x03, 0xE5, + 0xAF, 0x83, 0x03, 0xE5, 0xAF, 0x98, 0x03, 0xE5, + 0xAF, 0xB3, 0x04, 0xF0, 0xA1, 0xAC, 0x98, 0x03, + 0xE5, 0xAF, 0xBF, 0x03, 0xE5, 0xB0, 0x86, 0x03, + 0xE5, 0xBD, 0x93, 0x03, 0xE3, 0x9E, 0x81, 0x03, + 0xE5, 0xB1, 0xA0, 0x03, 0xE5, 0xB3, 0x80, 0x03, + 0xE5, 0xB2, 0x8D, 0x04, 0xF0, 0xA1, 0xB7, 0xA4, + // Bytes 3ec0 - 3eff + 0x03, 0xE5, 0xB5, 0x83, 0x04, 0xF0, 0xA1, 0xB7, + 0xA6, 0x03, 0xE5, 0xB5, 0xAE, 0x03, 0xE5, 0xB5, + 0xAB, 0x03, 0xE5, 0xB5, 0xBC, 0x03, 0xE5, 0xB7, + 0xA1, 0x03, 0xE5, 0xB7, 0xA2, 0x03, 0xE3, 0xA0, + 0xAF, 0x03, 0xE5, 0xB7, 0xBD, 0x03, 0xE5, 0xB8, + 0xA8, 0x03, 0xE5, 0xB8, 0xBD, 0x03, 0xE5, 0xB9, + 0xA9, 0x03, 0xE3, 0xA1, 0xA2, 0x04, 0xF0, 0xA2, + 0x86, 0x83, 0x03, 0xE3, 0xA1, 0xBC, 0x03, 0xE5, + // Bytes 3f00 - 3f3f + 0xBA, 0xB0, 0x03, 0xE5, 0xBA, 0xB3, 0x03, 0xE5, + 0xBA, 0xB6, 0x04, 0xF0, 0xAA, 0x8E, 0x92, 0x04, + 0xF0, 0xA2, 0x8C, 0xB1, 0x03, 0xE8, 0x88, 0x81, + 0x03, 0xE5, 0xBC, 0xA2, 0x03, 0xE3, 0xA3, 0x87, + 0x04, 0xF0, 0xA3, 0x8A, 0xB8, 0x04, 0xF0, 0xA6, + 0x87, 0x9A, 0x03, 0xE5, 0xBD, 0xA2, 0x03, 0xE5, + 0xBD, 0xAB, 0x03, 0xE3, 0xA3, 0xA3, 0x03, 0xE5, + 0xBE, 0x9A, 0x03, 0xE5, 0xBF, 0x8D, 0x03, 0xE5, + // Bytes 3f40 - 3f7f + 0xBF, 0x97, 0x03, 0xE5, 0xBF, 0xB9, 0x03, 0xE6, + 0x82, 0x81, 0x03, 0xE3, 0xA4, 0xBA, 0x03, 0xE3, + 0xA4, 0x9C, 0x04, 0xF0, 0xA2, 0x9B, 0x94, 0x03, + 0xE6, 0x83, 0x87, 0x03, 0xE6, 0x85, 0x88, 0x03, + 0xE6, 0x85, 0x8C, 0x03, 0xE6, 0x85, 0xBA, 0x03, + 0xE6, 0x86, 0xB2, 0x03, 0xE6, 0x86, 0xA4, 0x03, + 0xE6, 0x86, 0xAF, 0x03, 0xE6, 0x87, 0x9E, 0x03, + 0xE6, 0x88, 0x90, 0x03, 0xE6, 0x88, 0x9B, 0x03, + // Bytes 3f80 - 3fbf + 0xE6, 0x89, 0x9D, 0x03, 0xE6, 0x8A, 0xB1, 0x03, + 0xE6, 0x8B, 0x94, 0x03, 0xE6, 0x8D, 0x90, 0x04, + 0xF0, 0xA2, 0xAC, 0x8C, 0x03, 0xE6, 0x8C, 0xBD, + 0x03, 0xE6, 0x8B, 0xBC, 0x03, 0xE6, 0x8D, 0xA8, + 0x03, 0xE6, 0x8E, 0x83, 0x03, 0xE6, 0x8F, 0xA4, + 0x04, 0xF0, 0xA2, 0xAF, 0xB1, 0x03, 0xE6, 0x90, + 0xA2, 0x03, 0xE6, 0x8F, 0x85, 0x03, 0xE6, 0x8E, + 0xA9, 0x03, 0xE3, 0xA8, 0xAE, 0x03, 0xE6, 0x91, + // Bytes 3fc0 - 3fff + 0xA9, 0x03, 0xE6, 0x91, 0xBE, 0x03, 0xE6, 0x92, + 0x9D, 0x03, 0xE6, 0x91, 0xB7, 0x03, 0xE3, 0xA9, + 0xAC, 0x03, 0xE6, 0x95, 0xAC, 0x04, 0xF0, 0xA3, + 0x80, 0x8A, 0x03, 0xE6, 0x97, 0xA3, 0x03, 0xE6, + 0x9B, 0xB8, 0x03, 0xE6, 0x99, 0x89, 0x03, 0xE3, + 0xAC, 0x99, 0x03, 0xE3, 0xAC, 0x88, 0x03, 0xE3, + 0xAB, 0xA4, 0x03, 0xE5, 0x86, 0x92, 0x03, 0xE5, + 0x86, 0x95, 0x03, 0xE6, 0x9C, 0x80, 0x03, 0xE6, + // Bytes 4000 - 403f + 0x9A, 0x9C, 0x03, 0xE8, 0x82, 0xAD, 0x03, 0xE4, + 0x8F, 0x99, 0x03, 0xE6, 0x9C, 0xA1, 0x03, 0xE6, + 0x9D, 0x9E, 0x03, 0xE6, 0x9D, 0x93, 0x04, 0xF0, + 0xA3, 0x8F, 0x83, 0x03, 0xE3, 0xAD, 0x89, 0x03, + 0xE6, 0x9F, 0xBA, 0x03, 0xE6, 0x9E, 0x85, 0x03, + 0xE6, 0xA1, 0x92, 0x04, 0xF0, 0xA3, 0x91, 0xAD, + 0x03, 0xE6, 0xA2, 0x8E, 0x03, 0xE6, 0xA0, 0x9F, + 0x03, 0xE6, 0xA4, 0x94, 0x03, 0xE6, 0xA5, 0x82, + // Bytes 4040 - 407f + 0x03, 0xE6, 0xA6, 0xA3, 0x03, 0xE6, 0xA7, 0xAA, + 0x03, 0xE6, 0xAA, 0xA8, 0x04, 0xF0, 0xA3, 0x9A, + 0xA3, 0x03, 0xE6, 0xAB, 0x9B, 0x03, 0xE3, 0xB0, + 0x98, 0x03, 0xE6, 0xAC, 0xA1, 0x04, 0xF0, 0xA3, + 0xA2, 0xA7, 0x03, 0xE6, 0xAD, 0x94, 0x03, 0xE3, + 0xB1, 0x8E, 0x03, 0xE6, 0xAD, 0xB2, 0x03, 0xE6, + 0xAE, 0x9F, 0x03, 0xE6, 0xAE, 0xBB, 0x04, 0xF0, + 0xA3, 0xAA, 0x8D, 0x04, 0xF0, 0xA1, 0xB4, 0x8B, + // Bytes 4080 - 40bf + 0x04, 0xF0, 0xA3, 0xAB, 0xBA, 0x03, 0xE6, 0xB1, + 0x8E, 0x04, 0xF0, 0xA3, 0xB2, 0xBC, 0x03, 0xE6, + 0xB2, 0xBF, 0x03, 0xE6, 0xB3, 0x8D, 0x03, 0xE6, + 0xB1, 0xA7, 0x03, 0xE6, 0xB4, 0x96, 0x03, 0xE6, + 0xB4, 0xBE, 0x03, 0xE6, 0xB5, 0xA9, 0x03, 0xE6, + 0xB5, 0xB8, 0x03, 0xE6, 0xB6, 0x85, 0x04, 0xF0, + 0xA3, 0xB4, 0x9E, 0x03, 0xE6, 0xB4, 0xB4, 0x03, + 0xE6, 0xB8, 0xAF, 0x03, 0xE6, 0xB9, 0xAE, 0x03, + // Bytes 40c0 - 40ff + 0xE3, 0xB4, 0xB3, 0x03, 0xE6, 0xBB, 0x87, 0x04, + 0xF0, 0xA3, 0xBB, 0x91, 0x03, 0xE6, 0xB7, 0xB9, + 0x03, 0xE6, 0xBD, 0xAE, 0x04, 0xF0, 0xA3, 0xBD, + 0x9E, 0x04, 0xF0, 0xA3, 0xBE, 0x8E, 0x03, 0xE6, + 0xBF, 0x86, 0x03, 0xE7, 0x80, 0xB9, 0x03, 0xE7, + 0x80, 0x9B, 0x03, 0xE3, 0xB6, 0x96, 0x03, 0xE7, + 0x81, 0x8A, 0x03, 0xE7, 0x81, 0xBD, 0x03, 0xE7, + 0x81, 0xB7, 0x03, 0xE7, 0x82, 0xAD, 0x04, 0xF0, + // Bytes 4100 - 413f + 0xA0, 0x94, 0xA5, 0x03, 0xE7, 0x85, 0x85, 0x04, + 0xF0, 0xA4, 0x89, 0xA3, 0x03, 0xE7, 0x86, 0x9C, + 0x04, 0xF0, 0xA4, 0x8E, 0xAB, 0x03, 0xE7, 0x88, + 0xA8, 0x03, 0xE7, 0x89, 0x90, 0x04, 0xF0, 0xA4, + 0x98, 0x88, 0x03, 0xE7, 0x8A, 0x80, 0x03, 0xE7, + 0x8A, 0x95, 0x04, 0xF0, 0xA4, 0x9C, 0xB5, 0x04, + 0xF0, 0xA4, 0xA0, 0x94, 0x03, 0xE7, 0x8D, 0xBA, + 0x03, 0xE7, 0x8E, 0x8B, 0x03, 0xE3, 0xBA, 0xAC, + // Bytes 4140 - 417f + 0x03, 0xE7, 0x8E, 0xA5, 0x03, 0xE3, 0xBA, 0xB8, + 0x03, 0xE7, 0x91, 0x87, 0x03, 0xE7, 0x91, 0x9C, + 0x03, 0xE7, 0x92, 0x85, 0x03, 0xE7, 0x93, 0x8A, + 0x03, 0xE3, 0xBC, 0x9B, 0x03, 0xE7, 0x94, 0xA4, + 0x04, 0xF0, 0xA4, 0xB0, 0xB6, 0x03, 0xE7, 0x94, + 0xBE, 0x04, 0xF0, 0xA4, 0xB2, 0x92, 0x04, 0xF0, + 0xA2, 0x86, 0x9F, 0x03, 0xE7, 0x98, 0x90, 0x04, + 0xF0, 0xA4, 0xBE, 0xA1, 0x04, 0xF0, 0xA4, 0xBE, + // Bytes 4180 - 41bf + 0xB8, 0x04, 0xF0, 0xA5, 0x81, 0x84, 0x03, 0xE3, + 0xBF, 0xBC, 0x03, 0xE4, 0x80, 0x88, 0x04, 0xF0, + 0xA5, 0x83, 0xB3, 0x04, 0xF0, 0xA5, 0x83, 0xB2, + 0x04, 0xF0, 0xA5, 0x84, 0x99, 0x04, 0xF0, 0xA5, + 0x84, 0xB3, 0x03, 0xE7, 0x9C, 0x9E, 0x03, 0xE7, + 0x9C, 0x9F, 0x03, 0xE7, 0x9E, 0x8B, 0x03, 0xE4, + 0x81, 0x86, 0x03, 0xE4, 0x82, 0x96, 0x04, 0xF0, + 0xA5, 0x90, 0x9D, 0x03, 0xE7, 0xA1, 0x8E, 0x03, + // Bytes 41c0 - 41ff + 0xE4, 0x83, 0xA3, 0x04, 0xF0, 0xA5, 0x98, 0xA6, + 0x04, 0xF0, 0xA5, 0x9A, 0x9A, 0x04, 0xF0, 0xA5, + 0x9B, 0x85, 0x03, 0xE7, 0xA7, 0xAB, 0x03, 0xE4, + 0x84, 0xAF, 0x03, 0xE7, 0xA9, 0x8A, 0x03, 0xE7, + 0xA9, 0x8F, 0x04, 0xF0, 0xA5, 0xA5, 0xBC, 0x04, + 0xF0, 0xA5, 0xAA, 0xA7, 0x03, 0xE7, 0xAB, 0xAE, + 0x03, 0xE4, 0x88, 0x82, 0x04, 0xF0, 0xA5, 0xAE, + 0xAB, 0x03, 0xE7, 0xAF, 0x86, 0x03, 0xE7, 0xAF, + // Bytes 4200 - 423f + 0x89, 0x03, 0xE4, 0x88, 0xA7, 0x04, 0xF0, 0xA5, + 0xB2, 0x80, 0x03, 0xE7, 0xB3, 0x92, 0x03, 0xE4, + 0x8A, 0xA0, 0x03, 0xE7, 0xB3, 0xA8, 0x03, 0xE7, + 0xB3, 0xA3, 0x03, 0xE7, 0xB4, 0x80, 0x04, 0xF0, + 0xA5, 0xBE, 0x86, 0x03, 0xE7, 0xB5, 0xA3, 0x03, + 0xE4, 0x8C, 0x81, 0x03, 0xE7, 0xB7, 0x87, 0x03, + 0xE7, 0xB8, 0x82, 0x03, 0xE7, 0xB9, 0x85, 0x03, + 0xE4, 0x8C, 0xB4, 0x04, 0xF0, 0xA6, 0x88, 0xA8, + // Bytes 4240 - 427f + 0x04, 0xF0, 0xA6, 0x89, 0x87, 0x03, 0xE4, 0x8D, + 0x99, 0x04, 0xF0, 0xA6, 0x8B, 0x99, 0x03, 0xE7, + 0xBD, 0xBA, 0x04, 0xF0, 0xA6, 0x8C, 0xBE, 0x03, + 0xE7, 0xBE, 0x95, 0x03, 0xE7, 0xBF, 0xBA, 0x04, + 0xF0, 0xA6, 0x93, 0x9A, 0x04, 0xF0, 0xA6, 0x94, + 0xA3, 0x03, 0xE8, 0x81, 0xA0, 0x04, 0xF0, 0xA6, + 0x96, 0xA8, 0x03, 0xE8, 0x81, 0xB0, 0x04, 0xF0, + 0xA3, 0x8D, 0x9F, 0x03, 0xE4, 0x8F, 0x95, 0x03, + // Bytes 4280 - 42bf + 0xE8, 0x82, 0xB2, 0x03, 0xE8, 0x84, 0x83, 0x03, + 0xE4, 0x90, 0x8B, 0x03, 0xE8, 0x84, 0xBE, 0x03, + 0xE5, 0xAA, 0xB5, 0x04, 0xF0, 0xA6, 0x9E, 0xA7, + 0x04, 0xF0, 0xA6, 0x9E, 0xB5, 0x04, 0xF0, 0xA3, + 0x8E, 0x93, 0x04, 0xF0, 0xA3, 0x8E, 0x9C, 0x03, + 0xE8, 0x88, 0x84, 0x03, 0xE8, 0xBE, 0x9E, 0x03, + 0xE4, 0x91, 0xAB, 0x03, 0xE8, 0x8A, 0x91, 0x03, + 0xE8, 0x8A, 0x8B, 0x03, 0xE8, 0x8A, 0x9D, 0x03, + // Bytes 42c0 - 42ff + 0xE5, 0x8A, 0xB3, 0x03, 0xE8, 0x8A, 0xB1, 0x03, + 0xE8, 0x8A, 0xB3, 0x03, 0xE8, 0x8A, 0xBD, 0x03, + 0xE8, 0x8B, 0xA6, 0x04, 0xF0, 0xA6, 0xAC, 0xBC, + 0x03, 0xE8, 0x8C, 0x9D, 0x03, 0xE8, 0x8D, 0xA3, + 0x03, 0xE8, 0x8E, 0xAD, 0x03, 0xE8, 0x8C, 0xA3, + 0x03, 0xE8, 0x8E, 0xBD, 0x03, 0xE8, 0x8F, 0xA7, + 0x03, 0xE8, 0x8D, 0x93, 0x03, 0xE8, 0x8F, 0x8A, + 0x03, 0xE8, 0x8F, 0x8C, 0x03, 0xE8, 0x8F, 0x9C, + // Bytes 4300 - 433f + 0x04, 0xF0, 0xA6, 0xB0, 0xB6, 0x04, 0xF0, 0xA6, + 0xB5, 0xAB, 0x04, 0xF0, 0xA6, 0xB3, 0x95, 0x03, + 0xE4, 0x94, 0xAB, 0x03, 0xE8, 0x93, 0xB1, 0x03, + 0xE8, 0x93, 0xB3, 0x03, 0xE8, 0x94, 0x96, 0x04, + 0xF0, 0xA7, 0x8F, 0x8A, 0x03, 0xE8, 0x95, 0xA4, + 0x04, 0xF0, 0xA6, 0xBC, 0xAC, 0x03, 0xE4, 0x95, + 0x9D, 0x03, 0xE4, 0x95, 0xA1, 0x04, 0xF0, 0xA6, + 0xBE, 0xB1, 0x04, 0xF0, 0xA7, 0x83, 0x92, 0x03, + // Bytes 4340 - 437f + 0xE4, 0x95, 0xAB, 0x03, 0xE8, 0x99, 0x90, 0x03, + 0xE8, 0x99, 0xA7, 0x03, 0xE8, 0x99, 0xA9, 0x03, + 0xE8, 0x9A, 0xA9, 0x03, 0xE8, 0x9A, 0x88, 0x03, + 0xE8, 0x9C, 0x8E, 0x03, 0xE8, 0x9B, 0xA2, 0x03, + 0xE8, 0x9C, 0xA8, 0x03, 0xE8, 0x9D, 0xAB, 0x03, + 0xE8, 0x9E, 0x86, 0x03, 0xE4, 0x97, 0x97, 0x03, + 0xE8, 0x9F, 0xA1, 0x03, 0xE8, 0xA0, 0x81, 0x03, + 0xE4, 0x97, 0xB9, 0x03, 0xE8, 0xA1, 0xA0, 0x04, + // Bytes 4380 - 43bf + 0xF0, 0xA7, 0x99, 0xA7, 0x03, 0xE8, 0xA3, 0x97, + 0x03, 0xE8, 0xA3, 0x9E, 0x03, 0xE4, 0x98, 0xB5, + 0x03, 0xE8, 0xA3, 0xBA, 0x03, 0xE3, 0x92, 0xBB, + 0x04, 0xF0, 0xA7, 0xA2, 0xAE, 0x04, 0xF0, 0xA7, + 0xA5, 0xA6, 0x03, 0xE4, 0x9A, 0xBE, 0x03, 0xE4, + 0x9B, 0x87, 0x03, 0xE8, 0xAA, 0xA0, 0x04, 0xF0, + 0xA7, 0xB2, 0xA8, 0x03, 0xE8, 0xB2, 0xAB, 0x03, + 0xE8, 0xB3, 0x81, 0x03, 0xE8, 0xB4, 0x9B, 0x03, + // Bytes 43c0 - 43ff + 0xE8, 0xB5, 0xB7, 0x04, 0xF0, 0xA7, 0xBC, 0xAF, + 0x04, 0xF0, 0xA0, 0xA0, 0x84, 0x03, 0xE8, 0xB7, + 0x8B, 0x03, 0xE8, 0xB6, 0xBC, 0x03, 0xE8, 0xB7, + 0xB0, 0x04, 0xF0, 0xA0, 0xA3, 0x9E, 0x03, 0xE8, + 0xBB, 0x94, 0x04, 0xF0, 0xA8, 0x97, 0x92, 0x04, + 0xF0, 0xA8, 0x97, 0xAD, 0x03, 0xE9, 0x82, 0x94, + 0x03, 0xE9, 0x83, 0xB1, 0x03, 0xE9, 0x84, 0x91, + 0x04, 0xF0, 0xA8, 0x9C, 0xAE, 0x03, 0xE9, 0x84, + // Bytes 4400 - 443f + 0x9B, 0x03, 0xE9, 0x88, 0xB8, 0x03, 0xE9, 0x8B, + 0x97, 0x03, 0xE9, 0x8B, 0x98, 0x03, 0xE9, 0x89, + 0xBC, 0x03, 0xE9, 0x8F, 0xB9, 0x03, 0xE9, 0x90, + 0x95, 0x04, 0xF0, 0xA8, 0xAF, 0xBA, 0x03, 0xE9, + 0x96, 0x8B, 0x03, 0xE4, 0xA6, 0x95, 0x03, 0xE9, + 0x96, 0xB7, 0x04, 0xF0, 0xA8, 0xB5, 0xB7, 0x03, + 0xE4, 0xA7, 0xA6, 0x03, 0xE9, 0x9B, 0x83, 0x03, + 0xE5, 0xB6, 0xB2, 0x03, 0xE9, 0x9C, 0xA3, 0x04, + // Bytes 4440 - 447f + 0xF0, 0xA9, 0x85, 0x85, 0x04, 0xF0, 0xA9, 0x88, + 0x9A, 0x03, 0xE4, 0xA9, 0xAE, 0x03, 0xE4, 0xA9, + 0xB6, 0x03, 0xE9, 0x9F, 0xA0, 0x04, 0xF0, 0xA9, + 0x90, 0x8A, 0x03, 0xE4, 0xAA, 0xB2, 0x04, 0xF0, + 0xA9, 0x92, 0x96, 0x03, 0xE9, 0xA0, 0xA9, 0x04, + 0xF0, 0xA9, 0x96, 0xB6, 0x03, 0xE9, 0xA3, 0xA2, + 0x03, 0xE4, 0xAC, 0xB3, 0x03, 0xE9, 0xA4, 0xA9, + 0x03, 0xE9, 0xA6, 0xA7, 0x03, 0xE9, 0xA7, 0x82, + // Bytes 4480 - 44bf + 0x03, 0xE9, 0xA7, 0xBE, 0x03, 0xE4, 0xAF, 0x8E, + 0x04, 0xF0, 0xA9, 0xAC, 0xB0, 0x03, 0xE9, 0xB1, + 0x80, 0x03, 0xE9, 0xB3, 0xBD, 0x03, 0xE4, 0xB3, + 0x8E, 0x03, 0xE4, 0xB3, 0xAD, 0x03, 0xE9, 0xB5, + 0xA7, 0x04, 0xF0, 0xAA, 0x83, 0x8E, 0x03, 0xE4, + 0xB3, 0xB8, 0x04, 0xF0, 0xAA, 0x84, 0x85, 0x04, + 0xF0, 0xAA, 0x88, 0x8E, 0x04, 0xF0, 0xAA, 0x8A, + 0x91, 0x03, 0xE4, 0xB5, 0x96, 0x03, 0xE9, 0xBB, + // Bytes 44c0 - 44ff + 0xBE, 0x03, 0xE9, 0xBC, 0x85, 0x03, 0xE9, 0xBC, + 0x8F, 0x03, 0xE9, 0xBC, 0x96, 0x04, 0xF0, 0xAA, + 0x98, 0x80, +} + +// nfcDecompValues: 4992 entries, 9984 bytes +// Block 2 is the null block. +var nfcDecompValues = [4992]uint16{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0x00c0: 0x0032, 0x00c1: 0x0036, 0x00c2: 0x003a, 0x00c3: 0x003e, 0x00c4: 0x0042, 0x00c5: 0x0046, + 0x00c7: 0x004a, 0x00c8: 0x004e, 0x00c9: 0x0052, 0x00ca: 0x0056, 0x00cb: 0x005a, + 0x00cc: 0x005e, 0x00cd: 0x0062, 0x00ce: 0x0066, 0x00cf: 0x006a, 0x00d1: 0x006e, + 0x00d2: 0x0072, 0x00d3: 0x0076, 0x00d4: 0x007a, 0x00d5: 0x007e, 0x00d6: 0x0082, + 0x00d9: 0x0086, 0x00da: 0x008a, 0x00db: 0x008e, 0x00dc: 0x0092, 0x00dd: 0x0096, + 0x00e0: 0x009a, 0x00e1: 0x009e, 0x00e2: 0x00a2, 0x00e3: 0x00a6, + 0x00e4: 0x00aa, 0x00e5: 0x00ae, 0x00e7: 0x00b2, 0x00e8: 0x00b6, 0x00e9: 0x00ba, + 0x00ea: 0x00be, 0x00eb: 0x00c2, 0x00ec: 0x00c6, 0x00ed: 0x00ca, 0x00ee: 0x00ce, 0x00ef: 0x00d2, + 0x00f1: 0x00d6, 0x00f2: 0x00da, 0x00f3: 0x00de, 0x00f4: 0x00e2, 0x00f5: 0x00e6, + 0x00f6: 0x00ea, 0x00f9: 0x00ee, 0x00fa: 0x00f2, 0x00fb: 0x00f6, + 0x00fc: 0x00fa, 0x00fd: 0x00fe, 0x00ff: 0x0102, + // Block 0x4, offset 0x100 + 0x0100: 0x0106, 0x0101: 0x010a, 0x0102: 0x010e, 0x0103: 0x0112, 0x0104: 0x0116, 0x0105: 0x011a, + 0x0106: 0x011e, 0x0107: 0x0122, 0x0108: 0x0126, 0x0109: 0x012a, 0x010a: 0x012e, 0x010b: 0x0132, + 0x010c: 0x0136, 0x010d: 0x013a, 0x010e: 0x013e, 0x010f: 0x0142, + 0x0112: 0x0146, 0x0113: 0x014a, 0x0114: 0x014e, 0x0115: 0x0152, 0x0116: 0x0156, 0x0117: 0x015a, + 0x0118: 0x015e, 0x0119: 0x0162, 0x011a: 0x0166, 0x011b: 0x016a, 0x011c: 0x016e, 0x011d: 0x0172, + 0x011e: 0x0176, 0x011f: 0x017a, 0x0120: 0x017e, 0x0121: 0x0182, 0x0122: 0x0186, 0x0123: 0x018a, + 0x0124: 0x018e, 0x0125: 0x0192, 0x0128: 0x0196, 0x0129: 0x019a, + 0x012a: 0x019e, 0x012b: 0x01a2, 0x012c: 0x01a6, 0x012d: 0x01aa, 0x012e: 0x01ae, 0x012f: 0x01b2, + 0x0130: 0x01b6, 0x0134: 0x01c0, 0x0135: 0x01c4, + 0x0136: 0x01c8, 0x0137: 0x01cc, 0x0139: 0x01d0, 0x013a: 0x01d4, 0x013b: 0x01d8, + 0x013c: 0x01dc, 0x013d: 0x01e0, 0x013e: 0x01e4, + // Block 0x5, offset 0x140 + 0x0143: 0x01f0, 0x0144: 0x01f4, 0x0145: 0x01f8, + 0x0146: 0x01fc, 0x0147: 0x0200, 0x0148: 0x0204, + 0x014c: 0x020c, 0x014d: 0x0210, 0x014e: 0x0214, 0x014f: 0x0218, 0x0150: 0x021c, 0x0151: 0x0220, + 0x0154: 0x0224, 0x0155: 0x0228, 0x0156: 0x022c, 0x0157: 0x0230, + 0x0158: 0x0234, 0x0159: 0x0238, 0x015a: 0x023c, 0x015b: 0x0240, 0x015c: 0x0244, 0x015d: 0x0248, + 0x015e: 0x024c, 0x015f: 0x0250, 0x0160: 0x0254, 0x0161: 0x0258, 0x0162: 0x025c, 0x0163: 0x0260, + 0x0164: 0x0264, 0x0165: 0x0268, 0x0168: 0x026c, 0x0169: 0x0270, + 0x016a: 0x0274, 0x016b: 0x0278, 0x016c: 0x027c, 0x016d: 0x0280, 0x016e: 0x0284, 0x016f: 0x0288, + 0x0170: 0x028c, 0x0171: 0x0290, 0x0172: 0x0294, 0x0173: 0x0298, 0x0174: 0x029c, 0x0175: 0x02a0, + 0x0176: 0x02a4, 0x0177: 0x02a8, 0x0178: 0x02ac, 0x0179: 0x02b0, 0x017a: 0x02b4, 0x017b: 0x02b8, + 0x017c: 0x02bc, 0x017d: 0x02c0, 0x017e: 0x02c4, + // Block 0x6, offset 0x180 + 0x01a0: 0x02ca, 0x01a1: 0x02ce, + 0x01af: 0x02d2, + 0x01b0: 0x02d6, + // Block 0x7, offset 0x1c0 + 0x01cd: 0x02fb, 0x01ce: 0x02ff, 0x01cf: 0x0303, 0x01d0: 0x0307, 0x01d1: 0x030b, + 0x01d2: 0x030f, 0x01d3: 0x0313, 0x01d4: 0x0317, 0x01d5: 0x031b, 0x01d6: 0x0321, 0x01d7: 0x0327, + 0x01d8: 0x032d, 0x01d9: 0x0333, 0x01da: 0x0339, 0x01db: 0x033f, 0x01dc: 0x0345, + 0x01de: 0x034b, 0x01df: 0x0351, 0x01e0: 0x0357, 0x01e1: 0x035d, 0x01e2: 0x0363, 0x01e3: 0x0368, + 0x01e6: 0x036d, 0x01e7: 0x0371, 0x01e8: 0x0375, 0x01e9: 0x0379, + 0x01ea: 0x037d, 0x01eb: 0x0381, 0x01ec: 0x0385, 0x01ed: 0x038b, 0x01ee: 0x0391, 0x01ef: 0x0396, + 0x01f0: 0x039b, 0x01f4: 0x03a8, 0x01f5: 0x03ac, + 0x01f8: 0x03b0, 0x01f9: 0x03b4, 0x01fa: 0x03b8, 0x01fb: 0x03be, + 0x01fc: 0x03c4, 0x01fd: 0x03c9, 0x01fe: 0x03ce, 0x01ff: 0x03d3, + // Block 0x8, offset 0x200 + 0x0200: 0x03d8, 0x0201: 0x03dc, 0x0202: 0x03e0, 0x0203: 0x03e4, 0x0204: 0x03e8, 0x0205: 0x03ec, + 0x0206: 0x03f0, 0x0207: 0x03f4, 0x0208: 0x03f8, 0x0209: 0x03fc, 0x020a: 0x0400, 0x020b: 0x0404, + 0x020c: 0x0408, 0x020d: 0x040c, 0x020e: 0x0410, 0x020f: 0x0414, 0x0210: 0x0418, 0x0211: 0x041c, + 0x0212: 0x0420, 0x0213: 0x0424, 0x0214: 0x0428, 0x0215: 0x042c, 0x0216: 0x0430, 0x0217: 0x0434, + 0x0218: 0x0438, 0x0219: 0x043c, 0x021a: 0x0440, 0x021b: 0x0444, + 0x021e: 0x0448, 0x021f: 0x044c, + 0x0226: 0x0450, 0x0227: 0x0454, 0x0228: 0x0458, 0x0229: 0x045c, + 0x022a: 0x0460, 0x022b: 0x0466, 0x022c: 0x046c, 0x022d: 0x0472, 0x022e: 0x0478, 0x022f: 0x047c, + 0x0230: 0x0480, 0x0231: 0x0486, 0x0232: 0x048c, 0x0233: 0x0490, + // Block 0x9, offset 0x240 + 0x0240: 0x04cc, 0x0241: 0x04cf, 0x0243: 0x04d2, 0x0244: 0x04d5, + 0x0274: 0x04da, + 0x027e: 0x04e1, + // Block 0xa, offset 0x280 + 0x0285: 0x04e3, + 0x0286: 0x04ee, 0x0287: 0x04f3, 0x0288: 0x04f6, 0x0289: 0x04fb, 0x028a: 0x0500, + 0x028c: 0x0505, 0x028e: 0x050a, 0x028f: 0x050f, 0x0290: 0x0514, + 0x02aa: 0x051b, 0x02ab: 0x0520, 0x02ac: 0x0525, 0x02ad: 0x052a, 0x02ae: 0x052f, 0x02af: 0x0534, + 0x02b0: 0x0539, + // Block 0xb, offset 0x2c0 + 0x02ca: 0x0540, 0x02cb: 0x0545, + 0x02cc: 0x054a, 0x02cd: 0x054f, 0x02ce: 0x0554, + 0x02d3: 0x0562, 0x02d4: 0x0567, + // Block 0xc, offset 0x300 + 0x0300: 0x0584, 0x0301: 0x0589, 0x0303: 0x058e, + 0x0307: 0x0593, + 0x030c: 0x0598, 0x030d: 0x059d, 0x030e: 0x05a2, + 0x0319: 0x05a7, + 0x0339: 0x05ac, + // Block 0xd, offset 0x340 + 0x0350: 0x05b1, 0x0351: 0x05b6, + 0x0353: 0x05bb, 0x0357: 0x05c0, + 0x035c: 0x05c5, 0x035d: 0x05ca, + 0x035e: 0x05cf, + 0x0376: 0x05d4, 0x0377: 0x05d9, + // Block 0xe, offset 0x380 + 0x0381: 0x05de, 0x0382: 0x05e3, + 0x0390: 0x05e8, 0x0391: 0x05ed, + 0x0392: 0x05f2, 0x0393: 0x05f7, 0x0396: 0x05fc, 0x0397: 0x0601, + 0x039a: 0x0606, 0x039b: 0x060b, 0x039c: 0x0610, 0x039d: 0x0615, + 0x039e: 0x061a, 0x039f: 0x061f, 0x03a2: 0x0624, 0x03a3: 0x0629, + 0x03a4: 0x062e, 0x03a5: 0x0633, 0x03a6: 0x0638, 0x03a7: 0x063d, + 0x03aa: 0x0642, 0x03ab: 0x0647, 0x03ac: 0x064c, 0x03ad: 0x0651, 0x03ae: 0x0656, 0x03af: 0x065b, + 0x03b0: 0x0660, 0x03b1: 0x0665, 0x03b2: 0x066a, 0x03b3: 0x066f, 0x03b4: 0x0674, 0x03b5: 0x0679, + 0x03b8: 0x067e, 0x03b9: 0x0683, + // Block 0xf, offset 0x3c0 + 0x03e2: 0x068d, 0x03e3: 0x0692, + 0x03e4: 0x0697, 0x03e5: 0x069c, 0x03e6: 0x06a1, + // Block 0x10, offset 0x400 + 0x0400: 0x06ba, 0x0402: 0x06bf, + 0x0413: 0x06c4, + // Block 0x11, offset 0x440 + 0x0469: 0x06c9, + 0x0471: 0x06d0, 0x0474: 0x06d7, + // Block 0x12, offset 0x480 + 0x0498: 0x06de, 0x0499: 0x06e5, 0x049a: 0x06ec, 0x049b: 0x06f3, 0x049c: 0x06fa, 0x049d: 0x0701, + 0x049e: 0x0708, 0x049f: 0x070f, + // Block 0x13, offset 0x4c0 + 0x04cb: 0x0716, + 0x04cc: 0x071d, + 0x04dc: 0x0724, 0x04dd: 0x072b, + 0x04df: 0x0732, + // Block 0x14, offset 0x500 + 0x0533: 0x0739, + 0x0536: 0x0740, + // Block 0x15, offset 0x540 + 0x0559: 0x0747, 0x055a: 0x074e, 0x055b: 0x0755, + 0x055e: 0x075c, + // Block 0x16, offset 0x580 + 0x0588: 0x0763, 0x058b: 0x076a, + 0x058c: 0x0771, + 0x059c: 0x0778, 0x059d: 0x077f, + // Block 0x17, offset 0x5c0 + 0x05d4: 0x0786, + // Block 0x18, offset 0x600 + 0x060a: 0x078d, 0x060b: 0x0794, + 0x060c: 0x079b, + // Block 0x19, offset 0x640 + 0x0648: 0x07a2, + // Block 0x1a, offset 0x680 + 0x0680: 0x07a9, + 0x0687: 0x07b0, 0x0688: 0x07b7, 0x068a: 0x07be, 0x068b: 0x07c5, + // Block 0x1b, offset 0x6c0 + 0x06ca: 0x07cf, 0x06cb: 0x07d6, + 0x06cc: 0x07dd, + // Block 0x1c, offset 0x700 + 0x071a: 0x07e4, 0x071c: 0x07eb, 0x071d: 0x07f2, + 0x071e: 0x07fc, + // Block 0x1d, offset 0x740 + 0x0743: 0x0823, + 0x074d: 0x082a, + 0x0752: 0x0831, 0x0757: 0x0838, + 0x075c: 0x083f, + 0x0769: 0x0846, + 0x0773: 0x084d, 0x0775: 0x0854, + 0x0776: 0x085b, 0x0778: 0x086c, + // Block 0x1e, offset 0x780 + 0x0781: 0x087d, + 0x0793: 0x0884, + 0x079d: 0x088b, + 0x07a2: 0x0892, + 0x07a7: 0x0899, + 0x07ac: 0x08a0, + 0x07b9: 0x08a7, + // Block 0x1f, offset 0x7c0 + 0x07e6: 0x08ae, + // Block 0x20, offset 0x800 + 0x0806: 0x08b9, 0x0808: 0x08c0, 0x080a: 0x08c7, + 0x080c: 0x08ce, 0x080e: 0x08d5, + 0x0812: 0x08dc, + 0x083b: 0x08e3, + 0x083d: 0x08ea, + // Block 0x21, offset 0x840 + 0x0840: 0x08f1, 0x0841: 0x08f8, 0x0843: 0x08ff, + // Block 0x22, offset 0x880 + 0x0880: 0x09ea, 0x0881: 0x09ee, 0x0882: 0x09f2, 0x0883: 0x09f6, 0x0884: 0x09fa, 0x0885: 0x09fe, + 0x0886: 0x0a02, 0x0887: 0x0a06, 0x0888: 0x0a0a, 0x0889: 0x0a10, 0x088a: 0x0a16, 0x088b: 0x0a1a, + 0x088c: 0x0a1e, 0x088d: 0x0a22, 0x088e: 0x0a26, 0x088f: 0x0a2a, 0x0890: 0x0a2e, 0x0891: 0x0a32, + 0x0892: 0x0a36, 0x0893: 0x0a3a, 0x0894: 0x0a3e, 0x0895: 0x0a44, 0x0896: 0x0a4a, 0x0897: 0x0a50, + 0x0898: 0x0a56, 0x0899: 0x0a5a, 0x089a: 0x0a5e, 0x089b: 0x0a62, 0x089c: 0x0a66, 0x089d: 0x0a6c, + 0x089e: 0x0a72, 0x089f: 0x0a76, 0x08a0: 0x0a7a, 0x08a1: 0x0a7e, 0x08a2: 0x0a82, 0x08a3: 0x0a86, + 0x08a4: 0x0a8a, 0x08a5: 0x0a8e, 0x08a6: 0x0a92, 0x08a7: 0x0a96, 0x08a8: 0x0a9a, 0x08a9: 0x0a9e, + 0x08aa: 0x0aa2, 0x08ab: 0x0aa6, 0x08ac: 0x0aaa, 0x08ad: 0x0aae, 0x08ae: 0x0ab2, 0x08af: 0x0ab8, + 0x08b0: 0x0abe, 0x08b1: 0x0ac2, 0x08b2: 0x0ac6, 0x08b3: 0x0aca, 0x08b4: 0x0ace, 0x08b5: 0x0ad2, + 0x08b6: 0x0ad6, 0x08b7: 0x0ada, 0x08b8: 0x0ade, 0x08b9: 0x0ae4, 0x08ba: 0x0aea, 0x08bb: 0x0aee, + 0x08bc: 0x0af2, 0x08bd: 0x0af6, 0x08be: 0x0afa, 0x08bf: 0x0afe, + // Block 0x23, offset 0x8c0 + 0x08c0: 0x0b02, 0x08c1: 0x0b06, 0x08c2: 0x0b0a, 0x08c3: 0x0b0e, 0x08c4: 0x0b12, 0x08c5: 0x0b16, + 0x08c6: 0x0b1a, 0x08c7: 0x0b1e, 0x08c8: 0x0b22, 0x08c9: 0x0b26, 0x08ca: 0x0b2a, 0x08cb: 0x0b2e, + 0x08cc: 0x0b32, 0x08cd: 0x0b38, 0x08ce: 0x0b3e, 0x08cf: 0x0b44, 0x08d0: 0x0b4a, 0x08d1: 0x0b50, + 0x08d2: 0x0b56, 0x08d3: 0x0b5c, 0x08d4: 0x0b62, 0x08d5: 0x0b66, 0x08d6: 0x0b6a, 0x08d7: 0x0b6e, + 0x08d8: 0x0b72, 0x08d9: 0x0b76, 0x08da: 0x0b7a, 0x08db: 0x0b7e, 0x08dc: 0x0b82, 0x08dd: 0x0b88, + 0x08de: 0x0b8e, 0x08df: 0x0b92, 0x08e0: 0x0b96, 0x08e1: 0x0b9a, 0x08e2: 0x0b9e, 0x08e3: 0x0ba2, + 0x08e4: 0x0ba6, 0x08e5: 0x0bac, 0x08e6: 0x0bb2, 0x08e7: 0x0bb8, 0x08e8: 0x0bbe, 0x08e9: 0x0bc4, + 0x08ea: 0x0bca, 0x08eb: 0x0bce, 0x08ec: 0x0bd2, 0x08ed: 0x0bd6, 0x08ee: 0x0bda, 0x08ef: 0x0bde, + 0x08f0: 0x0be2, 0x08f1: 0x0be6, 0x08f2: 0x0bea, 0x08f3: 0x0bee, 0x08f4: 0x0bf2, 0x08f5: 0x0bf6, + 0x08f6: 0x0bfa, 0x08f7: 0x0bfe, 0x08f8: 0x0c02, 0x08f9: 0x0c08, 0x08fa: 0x0c0e, 0x08fb: 0x0c14, + 0x08fc: 0x0c1a, 0x08fd: 0x0c1e, 0x08fe: 0x0c22, 0x08ff: 0x0c26, + // Block 0x24, offset 0x900 + 0x0900: 0x0c2a, 0x0901: 0x0c2e, 0x0902: 0x0c32, 0x0903: 0x0c36, 0x0904: 0x0c3a, 0x0905: 0x0c3e, + 0x0906: 0x0c42, 0x0907: 0x0c46, 0x0908: 0x0c4a, 0x0909: 0x0c4e, 0x090a: 0x0c52, 0x090b: 0x0c56, + 0x090c: 0x0c5a, 0x090d: 0x0c5e, 0x090e: 0x0c62, 0x090f: 0x0c66, 0x0910: 0x0c6a, 0x0911: 0x0c6e, + 0x0912: 0x0c72, 0x0913: 0x0c76, 0x0914: 0x0c7a, 0x0915: 0x0c7e, 0x0916: 0x0c82, 0x0917: 0x0c86, + 0x0918: 0x0c8a, 0x0919: 0x0c8e, 0x091b: 0x0c96, + 0x0920: 0x0c9b, 0x0921: 0x0c9f, 0x0922: 0x0ca3, 0x0923: 0x0ca7, + 0x0924: 0x0cab, 0x0925: 0x0cb1, 0x0926: 0x0cb7, 0x0927: 0x0cbd, 0x0928: 0x0cc3, 0x0929: 0x0cc9, + 0x092a: 0x0ccf, 0x092b: 0x0cd5, 0x092c: 0x0cdb, 0x092d: 0x0ce1, 0x092e: 0x0ce7, 0x092f: 0x0ced, + 0x0930: 0x0cf3, 0x0931: 0x0cf9, 0x0932: 0x0cff, 0x0933: 0x0d05, 0x0934: 0x0d0b, 0x0935: 0x0d11, + 0x0936: 0x0d17, 0x0937: 0x0d1d, 0x0938: 0x0d23, 0x0939: 0x0d27, 0x093a: 0x0d2b, 0x093b: 0x0d2f, + 0x093c: 0x0d33, 0x093d: 0x0d37, 0x093e: 0x0d3b, 0x093f: 0x0d41, + // Block 0x25, offset 0x940 + 0x0940: 0x0d47, 0x0941: 0x0d4d, 0x0942: 0x0d53, 0x0943: 0x0d59, 0x0944: 0x0d5f, 0x0945: 0x0d65, + 0x0946: 0x0d6b, 0x0947: 0x0d71, 0x0948: 0x0d77, 0x0949: 0x0d7b, 0x094a: 0x0d7f, 0x094b: 0x0d83, + 0x094c: 0x0d87, 0x094d: 0x0d8b, 0x094e: 0x0d8f, 0x094f: 0x0d93, 0x0950: 0x0d97, 0x0951: 0x0d9d, + 0x0952: 0x0da3, 0x0953: 0x0da9, 0x0954: 0x0daf, 0x0955: 0x0db5, 0x0956: 0x0dbb, 0x0957: 0x0dc1, + 0x0958: 0x0dc7, 0x0959: 0x0dcd, 0x095a: 0x0dd3, 0x095b: 0x0dd9, 0x095c: 0x0ddf, 0x095d: 0x0de5, + 0x095e: 0x0deb, 0x095f: 0x0df1, 0x0960: 0x0df7, 0x0961: 0x0dfd, 0x0962: 0x0e03, 0x0963: 0x0e09, + 0x0964: 0x0e0f, 0x0965: 0x0e13, 0x0966: 0x0e17, 0x0967: 0x0e1b, 0x0968: 0x0e1f, 0x0969: 0x0e25, + 0x096a: 0x0e2b, 0x096b: 0x0e31, 0x096c: 0x0e37, 0x096d: 0x0e3d, 0x096e: 0x0e43, 0x096f: 0x0e49, + 0x0970: 0x0e4f, 0x0971: 0x0e55, 0x0972: 0x0e5b, 0x0973: 0x0e5f, 0x0974: 0x0e63, 0x0975: 0x0e67, + 0x0976: 0x0e6b, 0x0977: 0x0e6f, 0x0978: 0x0e73, 0x0979: 0x0e77, + // Block 0x26, offset 0x980 + 0x0980: 0x0e7b, 0x0981: 0x0e80, 0x0982: 0x0e85, 0x0983: 0x0e8c, 0x0984: 0x0e93, 0x0985: 0x0e9a, + 0x0986: 0x0ea1, 0x0987: 0x0ea8, 0x0988: 0x0eaf, 0x0989: 0x0eb4, 0x098a: 0x0eb9, 0x098b: 0x0ec0, + 0x098c: 0x0ec7, 0x098d: 0x0ece, 0x098e: 0x0ed5, 0x098f: 0x0edc, 0x0990: 0x0ee3, 0x0991: 0x0ee8, + 0x0992: 0x0eed, 0x0993: 0x0ef4, 0x0994: 0x0efb, 0x0995: 0x0f02, + 0x0998: 0x0f09, 0x0999: 0x0f0e, 0x099a: 0x0f13, 0x099b: 0x0f1a, 0x099c: 0x0f21, 0x099d: 0x0f28, + 0x09a0: 0x0f2f, 0x09a1: 0x0f34, 0x09a2: 0x0f39, 0x09a3: 0x0f40, + 0x09a4: 0x0f47, 0x09a5: 0x0f4e, 0x09a6: 0x0f55, 0x09a7: 0x0f5c, 0x09a8: 0x0f63, 0x09a9: 0x0f68, + 0x09aa: 0x0f6d, 0x09ab: 0x0f74, 0x09ac: 0x0f7b, 0x09ad: 0x0f82, 0x09ae: 0x0f89, 0x09af: 0x0f90, + 0x09b0: 0x0f97, 0x09b1: 0x0f9c, 0x09b2: 0x0fa1, 0x09b3: 0x0fa8, 0x09b4: 0x0faf, 0x09b5: 0x0fb6, + 0x09b6: 0x0fbd, 0x09b7: 0x0fc4, 0x09b8: 0x0fcb, 0x09b9: 0x0fd0, 0x09ba: 0x0fd5, 0x09bb: 0x0fdc, + 0x09bc: 0x0fe3, 0x09bd: 0x0fea, 0x09be: 0x0ff1, 0x09bf: 0x0ff8, + // Block 0x27, offset 0x9c0 + 0x09c0: 0x0fff, 0x09c1: 0x1004, 0x09c2: 0x1009, 0x09c3: 0x1010, 0x09c4: 0x1017, 0x09c5: 0x101e, + 0x09c8: 0x1025, 0x09c9: 0x102a, 0x09ca: 0x102f, 0x09cb: 0x1036, + 0x09cc: 0x103d, 0x09cd: 0x1044, 0x09d0: 0x104b, 0x09d1: 0x1050, + 0x09d2: 0x1055, 0x09d3: 0x105c, 0x09d4: 0x1063, 0x09d5: 0x106a, 0x09d6: 0x1071, 0x09d7: 0x1078, + 0x09d9: 0x107f, 0x09db: 0x1084, 0x09dd: 0x108b, + 0x09df: 0x1092, 0x09e0: 0x1099, 0x09e1: 0x109e, 0x09e2: 0x10a3, 0x09e3: 0x10aa, + 0x09e4: 0x10b1, 0x09e5: 0x10b8, 0x09e6: 0x10bf, 0x09e7: 0x10c6, 0x09e8: 0x10cd, 0x09e9: 0x10d2, + 0x09ea: 0x10d7, 0x09eb: 0x10de, 0x09ec: 0x10e5, 0x09ed: 0x10ec, 0x09ee: 0x10f3, 0x09ef: 0x10fa, + 0x09f0: 0x1101, 0x09f1: 0x0525, 0x09f2: 0x1106, 0x09f3: 0x052a, 0x09f4: 0x110b, 0x09f5: 0x052f, + 0x09f6: 0x1110, 0x09f7: 0x0534, 0x09f8: 0x1115, 0x09f9: 0x054a, 0x09fa: 0x111a, 0x09fb: 0x054f, + 0x09fc: 0x111f, 0x09fd: 0x0554, + // Block 0x28, offset 0xa00 + 0x0a00: 0x1124, 0x0a01: 0x112b, 0x0a02: 0x1132, 0x0a03: 0x113b, 0x0a04: 0x1144, 0x0a05: 0x114d, + 0x0a06: 0x1156, 0x0a07: 0x115f, 0x0a08: 0x1168, 0x0a09: 0x116f, 0x0a0a: 0x1176, 0x0a0b: 0x117f, + 0x0a0c: 0x1188, 0x0a0d: 0x1191, 0x0a0e: 0x119a, 0x0a0f: 0x11a3, 0x0a10: 0x11ac, 0x0a11: 0x11b3, + 0x0a12: 0x11ba, 0x0a13: 0x11c3, 0x0a14: 0x11cc, 0x0a15: 0x11d5, 0x0a16: 0x11de, 0x0a17: 0x11e7, + 0x0a18: 0x11f0, 0x0a19: 0x11f7, 0x0a1a: 0x11fe, 0x0a1b: 0x1207, 0x0a1c: 0x1210, 0x0a1d: 0x1219, + 0x0a1e: 0x1222, 0x0a1f: 0x122b, 0x0a20: 0x1234, 0x0a21: 0x123b, 0x0a22: 0x1242, 0x0a23: 0x124b, + 0x0a24: 0x1254, 0x0a25: 0x125d, 0x0a26: 0x1266, 0x0a27: 0x126f, 0x0a28: 0x1278, 0x0a29: 0x127f, + 0x0a2a: 0x1286, 0x0a2b: 0x128f, 0x0a2c: 0x1298, 0x0a2d: 0x12a1, 0x0a2e: 0x12aa, 0x0a2f: 0x12b3, + 0x0a30: 0x12bc, 0x0a31: 0x12c1, 0x0a32: 0x12c6, 0x0a33: 0x12cd, 0x0a34: 0x12d2, + 0x0a36: 0x12d9, 0x0a37: 0x12de, 0x0a38: 0x12e5, 0x0a39: 0x12ea, 0x0a3a: 0x12ef, 0x0a3b: 0x04ee, + 0x0a3c: 0x12f4, 0x0a3e: 0x12fd, + // Block 0x29, offset 0xa40 + 0x0a41: 0x1304, 0x0a42: 0x130f, 0x0a43: 0x1316, 0x0a44: 0x131b, + 0x0a46: 0x1322, 0x0a47: 0x1327, 0x0a48: 0x132e, 0x0a49: 0x04f6, 0x0a4a: 0x1333, 0x0a4b: 0x04fb, + 0x0a4c: 0x1338, 0x0a4d: 0x133d, 0x0a4e: 0x1349, 0x0a4f: 0x1355, 0x0a50: 0x1361, 0x0a51: 0x1366, + 0x0a52: 0x136b, 0x0a53: 0x0514, 0x0a56: 0x1372, 0x0a57: 0x1377, + 0x0a58: 0x137e, 0x0a59: 0x1383, 0x0a5a: 0x1388, 0x0a5b: 0x0500, 0x0a5d: 0x138d, + 0x0a5e: 0x1399, 0x0a5f: 0x13a5, 0x0a60: 0x13b1, 0x0a61: 0x13b6, 0x0a62: 0x13bb, 0x0a63: 0x0539, + 0x0a64: 0x13c2, 0x0a65: 0x13c7, 0x0a66: 0x13cc, 0x0a67: 0x13d1, 0x0a68: 0x13d8, 0x0a69: 0x13dd, + 0x0a6a: 0x13e2, 0x0a6b: 0x050a, 0x0a6c: 0x13e7, 0x0a6d: 0x13ec, 0x0a6e: 0x04e3, 0x0a6f: 0x13f7, + 0x0a72: 0x13f9, 0x0a73: 0x1400, 0x0a74: 0x1405, + 0x0a76: 0x140c, 0x0a77: 0x1411, 0x0a78: 0x1418, 0x0a79: 0x0505, 0x0a7a: 0x141d, 0x0a7b: 0x050f, + 0x0a7c: 0x1422, 0x0a7d: 0x1427, + // Block 0x2a, offset 0xa80 + 0x0a80: 0x142e, 0x0a81: 0x1432, + // Block 0x2b, offset 0xac0 + 0x0ae6: 0x14d6, + 0x0aea: 0x091c, 0x0aeb: 0x0046, + // Block 0x2c, offset 0xb00 + 0x0b1a: 0x159f, 0x0b1b: 0x15a5, + 0x0b2e: 0x15ab, + // Block 0x2d, offset 0xb40 + 0x0b4d: 0x15b1, 0x0b4e: 0x15b7, 0x0b4f: 0x15bd, + // Block 0x2e, offset 0xb80 + 0x0b84: 0x15c3, + 0x0b89: 0x15c9, + 0x0b8c: 0x15cf, + 0x0ba4: 0x15d5, 0x0ba6: 0x15db, + // Block 0x2f, offset 0xbc0 + 0x0bc1: 0x1603, 0x0bc4: 0x1609, + 0x0bc7: 0x160f, 0x0bc9: 0x1615, + 0x0be0: 0x161b, 0x0be2: 0x161f, + 0x0bed: 0x1625, 0x0bee: 0x162b, 0x0bef: 0x162f, + 0x0bf0: 0x1633, 0x0bf1: 0x1639, 0x0bf4: 0x163f, 0x0bf5: 0x1645, + 0x0bf8: 0x164b, 0x0bf9: 0x1651, + // Block 0x30, offset 0xc00 + 0x0c00: 0x1657, 0x0c01: 0x165d, 0x0c04: 0x1663, 0x0c05: 0x1669, + 0x0c08: 0x166f, 0x0c09: 0x1675, + 0x0c2c: 0x167b, 0x0c2d: 0x1681, 0x0c2e: 0x1687, 0x0c2f: 0x168d, + // Block 0x31, offset 0xc40 + 0x0c60: 0x1693, 0x0c61: 0x1699, 0x0c62: 0x169f, 0x0c63: 0x16a5, + 0x0c6a: 0x16ab, 0x0c6b: 0x16b1, 0x0c6c: 0x16b7, 0x0c6d: 0x16bd, + // Block 0x32, offset 0xc80 + 0x0ca9: 0x16c3, + 0x0caa: 0x16c7, + // Block 0x33, offset 0xcc0 + 0x0cdc: 0x1814, + // Block 0x34, offset 0xd00 + 0x0d0c: 0x1b8a, 0x0d0e: 0x1b91, 0x0d10: 0x1b98, + 0x0d12: 0x1b9f, 0x0d14: 0x1ba6, 0x0d16: 0x1bad, + 0x0d18: 0x1bb4, 0x0d1a: 0x1bbb, 0x0d1c: 0x1bc2, + 0x0d1e: 0x1bc9, 0x0d20: 0x1bd0, 0x0d22: 0x1bd7, + 0x0d25: 0x1bde, 0x0d27: 0x1be5, 0x0d29: 0x1bec, + 0x0d30: 0x1bf3, 0x0d31: 0x1bfa, 0x0d33: 0x1c01, 0x0d34: 0x1c08, + 0x0d36: 0x1c0f, 0x0d37: 0x1c16, 0x0d39: 0x1c1d, 0x0d3a: 0x1c24, + 0x0d3c: 0x1c2b, 0x0d3d: 0x1c32, + // Block 0x35, offset 0xd40 + 0x0d54: 0x1c39, + 0x0d5e: 0x1c4a, + 0x0d6c: 0x1c58, 0x0d6e: 0x1c5f, + 0x0d70: 0x1c66, 0x0d72: 0x1c6d, 0x0d74: 0x1c74, + 0x0d76: 0x1c7b, 0x0d78: 0x1c82, 0x0d7a: 0x1c89, + 0x0d7c: 0x1c90, 0x0d7e: 0x1c97, + // Block 0x36, offset 0xd80 + 0x0d80: 0x1c9e, 0x0d82: 0x1ca5, 0x0d85: 0x1cac, + 0x0d87: 0x1cb3, 0x0d89: 0x1cba, + 0x0d90: 0x1cc1, 0x0d91: 0x1cc8, + 0x0d93: 0x1ccf, 0x0d94: 0x1cd6, 0x0d96: 0x1cdd, 0x0d97: 0x1ce4, + 0x0d99: 0x1ceb, 0x0d9a: 0x1cf2, 0x0d9c: 0x1cf9, 0x0d9d: 0x1d00, + 0x0db4: 0x1d07, + 0x0db7: 0x1d0e, 0x0db8: 0x1d15, 0x0db9: 0x1d1c, 0x0dba: 0x1d23, + 0x0dbe: 0x1d2a, + // Block 0x37, offset 0xdc0 + 0x0dc0: 0x2a81, 0x0dc1: 0x2a85, 0x0dc2: 0x1a9e, 0x0dc3: 0x2a89, 0x0dc4: 0x2a8d, 0x0dc5: 0x2a91, + 0x0dc6: 0x2a95, 0x0dc7: 0x1b76, 0x0dc8: 0x1b76, 0x0dc9: 0x2a99, 0x0dca: 0x1abe, 0x0dcb: 0x2a9d, + 0x0dcc: 0x2aa1, 0x0dcd: 0x2aa5, 0x0dce: 0x2aa9, 0x0dcf: 0x2aad, 0x0dd0: 0x2ab1, 0x0dd1: 0x2ab5, + 0x0dd2: 0x2ab9, 0x0dd3: 0x2abd, 0x0dd4: 0x2ac1, 0x0dd5: 0x2ac5, 0x0dd6: 0x2ac9, 0x0dd7: 0x2acd, + 0x0dd8: 0x2ad1, 0x0dd9: 0x2ad5, 0x0dda: 0x2ad9, 0x0ddb: 0x2add, 0x0ddc: 0x2ae1, 0x0ddd: 0x2ae5, + 0x0dde: 0x2ae9, 0x0ddf: 0x2aed, 0x0de0: 0x2af1, 0x0de1: 0x2af5, 0x0de2: 0x2af9, 0x0de3: 0x2afd, + 0x0de4: 0x2b01, 0x0de5: 0x2b05, 0x0de6: 0x2b09, 0x0de7: 0x2b0d, 0x0de8: 0x2b11, 0x0de9: 0x2b15, + 0x0dea: 0x2b19, 0x0deb: 0x2b1d, 0x0dec: 0x2b21, 0x0ded: 0x2b25, 0x0dee: 0x2b29, 0x0def: 0x2b2d, + 0x0df0: 0x2b31, 0x0df1: 0x2b35, 0x0df2: 0x2b39, 0x0df3: 0x2b3d, 0x0df4: 0x1a16, 0x0df5: 0x2b41, + 0x0df6: 0x2b45, 0x0df7: 0x2b49, 0x0df8: 0x2b4d, 0x0df9: 0x2b51, 0x0dfa: 0x2b55, 0x0dfb: 0x2b59, + 0x0dfc: 0x2b5d, 0x0dfd: 0x2b61, 0x0dfe: 0x2b65, 0x0dff: 0x2b69, + // Block 0x38, offset 0xe00 + 0x0e00: 0x1b3a, 0x0e01: 0x2b6d, 0x0e02: 0x2b71, 0x0e03: 0x2b75, 0x0e04: 0x2b79, 0x0e05: 0x2b7d, + 0x0e06: 0x2b81, 0x0e07: 0x2b85, 0x0e08: 0x2b89, 0x0e09: 0x2b8d, 0x0e0a: 0x2b91, 0x0e0b: 0x2b95, + 0x0e0c: 0x2b99, 0x0e0d: 0x2b9d, 0x0e0e: 0x2ba1, 0x0e0f: 0x2ba5, 0x0e10: 0x2ba9, 0x0e11: 0x2bad, + 0x0e12: 0x2bb1, 0x0e13: 0x2bb5, 0x0e14: 0x2bb9, 0x0e15: 0x2bbd, 0x0e16: 0x2bc1, 0x0e17: 0x2bc5, + 0x0e18: 0x2bc9, 0x0e19: 0x2bcd, 0x0e1a: 0x2bd1, 0x0e1b: 0x2bd5, 0x0e1c: 0x2ac1, 0x0e1d: 0x2bd9, + 0x0e1e: 0x2bdd, 0x0e1f: 0x2be1, 0x0e20: 0x2be5, 0x0e21: 0x2be9, 0x0e22: 0x2bed, 0x0e23: 0x2bf1, + 0x0e24: 0x2bf5, 0x0e25: 0x2bf9, 0x0e26: 0x2bfd, 0x0e27: 0x2c01, 0x0e28: 0x2c05, 0x0e29: 0x2c09, + 0x0e2a: 0x2c0d, 0x0e2b: 0x2c11, 0x0e2c: 0x2c15, 0x0e2d: 0x2c19, 0x0e2e: 0x2c1d, 0x0e2f: 0x2c21, + 0x0e30: 0x2c25, 0x0e31: 0x1aa6, 0x0e32: 0x2c29, 0x0e33: 0x2c2d, 0x0e34: 0x2c31, 0x0e35: 0x2c35, + 0x0e36: 0x2c39, 0x0e37: 0x2c3d, 0x0e38: 0x2c41, 0x0e39: 0x2c45, 0x0e3a: 0x2c49, 0x0e3b: 0x2c4d, + 0x0e3c: 0x2c51, 0x0e3d: 0x2c55, 0x0e3e: 0x2c59, 0x0e3f: 0x2c5d, + // Block 0x39, offset 0xe40 + 0x0e40: 0x2c61, 0x0e41: 0x18ba, 0x0e42: 0x2c65, 0x0e43: 0x2c69, 0x0e44: 0x2c6d, 0x0e45: 0x2c71, + 0x0e46: 0x2c75, 0x0e47: 0x2c79, 0x0e48: 0x2c7d, 0x0e49: 0x2c81, 0x0e4a: 0x186e, 0x0e4b: 0x2c85, + 0x0e4c: 0x2c89, 0x0e4d: 0x2c8d, 0x0e4e: 0x2c91, 0x0e4f: 0x2c95, 0x0e50: 0x2c99, 0x0e51: 0x2c9d, + 0x0e52: 0x2ca1, 0x0e53: 0x2ca5, 0x0e54: 0x2ca9, 0x0e55: 0x2cad, 0x0e56: 0x2cb1, 0x0e57: 0x2cb5, + 0x0e58: 0x2cb9, 0x0e59: 0x2cbd, 0x0e5a: 0x2cc1, 0x0e5b: 0x2cc5, 0x0e5c: 0x2cc9, 0x0e5d: 0x2ccd, + 0x0e5e: 0x2cd1, 0x0e5f: 0x2cd5, 0x0e60: 0x2cd9, 0x0e61: 0x2c21, 0x0e62: 0x2cdd, 0x0e63: 0x2ce1, + 0x0e64: 0x2ce5, 0x0e65: 0x2ce9, 0x0e66: 0x2ced, 0x0e67: 0x2cf1, 0x0e68: 0x2cf5, 0x0e69: 0x2cf9, + 0x0e6a: 0x2be1, 0x0e6b: 0x2cfd, 0x0e6c: 0x2d01, 0x0e6d: 0x2d05, 0x0e6e: 0x2d09, 0x0e6f: 0x2d0d, + 0x0e70: 0x2d11, 0x0e71: 0x2d15, 0x0e72: 0x2d19, 0x0e73: 0x2d1d, 0x0e74: 0x2d21, 0x0e75: 0x2d25, + 0x0e76: 0x2d29, 0x0e77: 0x2d2d, 0x0e78: 0x2d31, 0x0e79: 0x2d35, 0x0e7a: 0x2d39, 0x0e7b: 0x2d3d, + 0x0e7c: 0x2d41, 0x0e7d: 0x2d45, 0x0e7e: 0x2d49, 0x0e7f: 0x2ac1, + // Block 0x3a, offset 0xe80 + 0x0e80: 0x2d4d, 0x0e81: 0x2d51, 0x0e82: 0x2d55, 0x0e83: 0x2d59, 0x0e84: 0x1b72, 0x0e85: 0x2d5d, + 0x0e86: 0x2d61, 0x0e87: 0x2d65, 0x0e88: 0x2d69, 0x0e89: 0x2d6d, 0x0e8a: 0x2d71, 0x0e8b: 0x2d75, + 0x0e8c: 0x2d79, 0x0e8d: 0x2d7d, 0x0e8e: 0x2d81, 0x0e8f: 0x2d85, 0x0e90: 0x2d89, 0x0e91: 0x2173, + 0x0e92: 0x2d8d, 0x0e93: 0x2d91, 0x0e94: 0x2d95, 0x0e95: 0x2d99, 0x0e96: 0x2d9d, 0x0e97: 0x2da1, + 0x0e98: 0x2da5, 0x0e99: 0x2da9, 0x0e9a: 0x2dad, 0x0e9b: 0x2be9, 0x0e9c: 0x2db1, 0x0e9d: 0x2db5, + 0x0e9e: 0x2db9, 0x0e9f: 0x2dbd, 0x0ea0: 0x2dc1, 0x0ea1: 0x2dc5, 0x0ea2: 0x2dc9, 0x0ea3: 0x2dcd, + 0x0ea4: 0x2dd1, 0x0ea5: 0x2dd5, 0x0ea6: 0x2dd9, 0x0ea7: 0x2ddd, 0x0ea8: 0x2de1, 0x0ea9: 0x1aba, + 0x0eaa: 0x2de5, 0x0eab: 0x2de9, 0x0eac: 0x2ded, 0x0ead: 0x2df1, 0x0eae: 0x2df5, 0x0eaf: 0x2df9, + 0x0eb0: 0x2dfd, 0x0eb1: 0x2e01, 0x0eb2: 0x2e05, 0x0eb3: 0x2e09, 0x0eb4: 0x2e0d, 0x0eb5: 0x2e11, + 0x0eb6: 0x2e15, 0x0eb7: 0x19f6, 0x0eb8: 0x2e19, 0x0eb9: 0x2e1d, 0x0eba: 0x2e21, 0x0ebb: 0x2e25, + 0x0ebc: 0x2e29, 0x0ebd: 0x2e2d, 0x0ebe: 0x2e31, 0x0ebf: 0x2e35, + // Block 0x3b, offset 0xec0 + 0x0ec0: 0x2e39, 0x0ec1: 0x2e3d, 0x0ec2: 0x2e41, 0x0ec3: 0x2e45, 0x0ec4: 0x2e49, 0x0ec5: 0x2e4d, + 0x0ec6: 0x2e51, 0x0ec7: 0x2e55, 0x0ec8: 0x1a62, 0x0ec9: 0x2e59, 0x0eca: 0x1a6e, 0x0ecb: 0x2e5d, + 0x0ecc: 0x2e61, 0x0ecd: 0x2e65, 0x0ed0: 0x2e69, + 0x0ed2: 0x2e6d, 0x0ed5: 0x2e71, 0x0ed6: 0x2e75, 0x0ed7: 0x2e79, + 0x0ed8: 0x2e7d, 0x0ed9: 0x2e81, 0x0eda: 0x2e85, 0x0edb: 0x2e89, 0x0edc: 0x2e8d, 0x0edd: 0x2e91, + 0x0ede: 0x1a12, 0x0ee0: 0x2e95, 0x0ee2: 0x2e99, + 0x0ee5: 0x2e9d, 0x0ee6: 0x2ea1, + 0x0eea: 0x2ea5, 0x0eeb: 0x2ea9, 0x0eec: 0x2ead, 0x0eed: 0x2eb1, + 0x0ef0: 0x2eb5, 0x0ef1: 0x2eb9, 0x0ef2: 0x2ebd, 0x0ef3: 0x2ec1, 0x0ef4: 0x2ec5, 0x0ef5: 0x2ec9, + 0x0ef6: 0x2ecd, 0x0ef7: 0x2ed1, 0x0ef8: 0x2ed5, 0x0ef9: 0x2ed9, 0x0efa: 0x2edd, 0x0efb: 0x2ee1, + 0x0efc: 0x18d6, 0x0efd: 0x2ee5, 0x0efe: 0x2ee9, 0x0eff: 0x2eed, + // Block 0x3c, offset 0xf00 + 0x0f00: 0x2ef1, 0x0f01: 0x2ef5, 0x0f02: 0x2ef9, 0x0f03: 0x2efd, 0x0f04: 0x2f01, 0x0f05: 0x2f05, + 0x0f06: 0x2f09, 0x0f07: 0x2f0d, 0x0f08: 0x2f11, 0x0f09: 0x2f15, 0x0f0a: 0x2f19, 0x0f0b: 0x2f1d, + 0x0f0c: 0x2187, 0x0f0d: 0x2f21, 0x0f0e: 0x2f25, 0x0f0f: 0x2f29, 0x0f10: 0x2f2d, 0x0f11: 0x2197, + 0x0f12: 0x2f31, 0x0f13: 0x2f35, 0x0f14: 0x2f39, 0x0f15: 0x2f3d, 0x0f16: 0x2f41, 0x0f17: 0x2cb1, + 0x0f18: 0x2f45, 0x0f19: 0x2f49, 0x0f1a: 0x2f4d, 0x0f1b: 0x2f51, 0x0f1c: 0x2f55, 0x0f1d: 0x2f59, + 0x0f1e: 0x2f59, 0x0f1f: 0x2f5d, 0x0f20: 0x2f61, 0x0f21: 0x2f65, 0x0f22: 0x2f69, 0x0f23: 0x2f6d, + 0x0f24: 0x2f71, 0x0f25: 0x2f75, 0x0f26: 0x2f79, 0x0f27: 0x2e9d, 0x0f28: 0x2f7d, 0x0f29: 0x2f81, + 0x0f2a: 0x2f85, 0x0f2b: 0x2f89, 0x0f2c: 0x2f8d, 0x0f2d: 0x2f92, + 0x0f30: 0x2f96, 0x0f31: 0x2f9a, 0x0f32: 0x2f9e, 0x0f33: 0x2fa2, 0x0f34: 0x2fa6, 0x0f35: 0x2faa, + 0x0f36: 0x2fae, 0x0f37: 0x2fb2, 0x0f38: 0x2ecd, 0x0f39: 0x2fb6, 0x0f3a: 0x2fba, 0x0f3b: 0x2fbe, + 0x0f3c: 0x2e69, 0x0f3d: 0x2fc2, 0x0f3e: 0x2fc6, 0x0f3f: 0x2fca, + // Block 0x3d, offset 0xf40 + 0x0f40: 0x2fce, 0x0f41: 0x2fd2, 0x0f42: 0x2fd6, 0x0f43: 0x2fda, 0x0f44: 0x2fde, 0x0f45: 0x2fe2, + 0x0f46: 0x2fe6, 0x0f47: 0x2fea, 0x0f48: 0x2fee, 0x0f49: 0x2eed, 0x0f4a: 0x2ff2, 0x0f4b: 0x2ef1, + 0x0f4c: 0x2ff6, 0x0f4d: 0x2ffa, 0x0f4e: 0x2ffe, 0x0f4f: 0x3002, 0x0f50: 0x3006, 0x0f51: 0x2e6d, + 0x0f52: 0x2b15, 0x0f53: 0x300a, 0x0f54: 0x300e, 0x0f55: 0x195a, 0x0f56: 0x2c25, 0x0f57: 0x2d71, + 0x0f58: 0x3012, 0x0f59: 0x3016, 0x0f5a: 0x2f0d, 0x0f5b: 0x301a, 0x0f5c: 0x2f11, 0x0f5d: 0x301e, + 0x0f5e: 0x3022, 0x0f5f: 0x3026, 0x0f60: 0x2e75, 0x0f61: 0x302a, 0x0f62: 0x302e, 0x0f63: 0x3032, + 0x0f64: 0x3036, 0x0f65: 0x303a, 0x0f66: 0x2e79, 0x0f67: 0x303e, 0x0f68: 0x3042, 0x0f69: 0x3046, + 0x0f6a: 0x304a, 0x0f6b: 0x304e, 0x0f6c: 0x3052, 0x0f6d: 0x2f41, 0x0f6e: 0x3056, 0x0f6f: 0x305a, + 0x0f70: 0x2cb1, 0x0f71: 0x305e, 0x0f72: 0x2f51, 0x0f73: 0x3062, 0x0f74: 0x3066, 0x0f75: 0x306a, + 0x0f76: 0x306e, 0x0f77: 0x3072, 0x0f78: 0x2f65, 0x0f79: 0x3076, 0x0f7a: 0x2e99, 0x0f7b: 0x307a, + 0x0f7c: 0x2f69, 0x0f7d: 0x2bd9, 0x0f7e: 0x307e, 0x0f7f: 0x2f6d, + // Block 0x3e, offset 0xf80 + 0x0f80: 0x3082, 0x0f81: 0x2f75, 0x0f82: 0x3086, 0x0f83: 0x308a, 0x0f84: 0x308e, 0x0f85: 0x3092, + 0x0f86: 0x3096, 0x0f87: 0x2f7d, 0x0f88: 0x2e8d, 0x0f89: 0x309a, 0x0f8a: 0x2f81, 0x0f8b: 0x309e, + 0x0f8c: 0x2f85, 0x0f8d: 0x30a2, 0x0f8e: 0x1b76, 0x0f8f: 0x30a6, 0x0f90: 0x30ab, 0x0f91: 0x30b0, + 0x0f92: 0x30b5, 0x0f93: 0x30b9, 0x0f94: 0x30bd, 0x0f95: 0x30c1, 0x0f96: 0x30c6, 0x0f97: 0x30cb, + 0x0f98: 0x30d0, 0x0f99: 0x30d4, + // Block 0x3f, offset 0xfc0 + 0x0fdd: 0x3105, + 0x0fdf: 0x310a, + 0x0fea: 0x3124, 0x0feb: 0x3129, 0x0fec: 0x312e, 0x0fed: 0x3135, 0x0fee: 0x313c, 0x0fef: 0x3141, + 0x0ff0: 0x3146, 0x0ff1: 0x314b, 0x0ff2: 0x3150, 0x0ff3: 0x3155, 0x0ff4: 0x315a, 0x0ff5: 0x315f, + 0x0ff6: 0x3164, 0x0ff8: 0x3169, 0x0ff9: 0x316e, 0x0ffa: 0x3173, 0x0ffb: 0x3178, + 0x0ffc: 0x317d, 0x0ffe: 0x3182, + // Block 0x40, offset 0x1000 + 0x1000: 0x3187, 0x1001: 0x318c, 0x1003: 0x3191, 0x1004: 0x3196, + 0x1006: 0x319b, 0x1007: 0x31a0, 0x1008: 0x31a5, 0x1009: 0x31aa, 0x100a: 0x31af, 0x100b: 0x31b4, + 0x100c: 0x31b9, 0x100d: 0x31be, 0x100e: 0x31c3, + // Block 0x41, offset 0x1040 + 0x105a: 0x3a73, 0x105c: 0x3a7c, + 0x106b: 0x3a85, + // Block 0x42, offset 0x1080 + 0x109e: 0x3a8e, 0x109f: 0x3a97, 0x10a0: 0x3aa0, 0x10a1: 0x3aad, 0x10a2: 0x3aba, 0x10a3: 0x3ac7, + 0x10a4: 0x3ad4, + // Block 0x43, offset 0x10c0 + 0x10fb: 0x3ae1, + 0x10fc: 0x3aea, 0x10fd: 0x3af3, 0x10fe: 0x3b00, 0x10ff: 0x3b0d, + // Block 0x44, offset 0x1100 + 0x1100: 0x3b1a, + // Block 0x45, offset 0x1140 + 0x1140: 0x3d23, 0x1141: 0x3d27, 0x1142: 0x3d2b, 0x1143: 0x3d2f, 0x1144: 0x3d34, 0x1145: 0x2eb5, + 0x1146: 0x3d38, 0x1147: 0x3d3c, 0x1148: 0x3d40, 0x1149: 0x3d44, 0x114a: 0x2eb9, 0x114b: 0x3d48, + 0x114c: 0x3d4c, 0x114d: 0x3d50, 0x114e: 0x2ebd, 0x114f: 0x3d55, 0x1150: 0x3d59, 0x1151: 0x3d5d, + 0x1152: 0x3d61, 0x1153: 0x3d66, 0x1154: 0x3d6a, 0x1155: 0x3c71, 0x1156: 0x3d6e, 0x1157: 0x3d73, + 0x1158: 0x3d77, 0x1159: 0x3d7b, 0x115a: 0x3d7f, 0x115b: 0x2f9a, 0x115c: 0x3d83, 0x115d: 0x1866, + 0x115e: 0x3d88, 0x115f: 0x3d8c, 0x1160: 0x3d90, 0x1161: 0x3d94, 0x1162: 0x3cb9, 0x1163: 0x3d98, + 0x1164: 0x3d9c, 0x1165: 0x2fae, 0x1166: 0x2ec1, 0x1167: 0x2ec5, 0x1168: 0x2fb2, 0x1169: 0x3da0, + 0x116a: 0x3da4, 0x116b: 0x2bf1, 0x116c: 0x3da8, 0x116d: 0x2ec9, 0x116e: 0x3dac, 0x116f: 0x3db0, + 0x1170: 0x3db4, 0x1171: 0x3db8, 0x1172: 0x3db8, 0x1173: 0x3db8, 0x1174: 0x3dbc, 0x1175: 0x3dc1, + 0x1176: 0x3dc5, 0x1177: 0x3dc9, 0x1178: 0x3dcd, 0x1179: 0x3dd2, 0x117a: 0x3dd6, 0x117b: 0x3dda, + 0x117c: 0x3dde, 0x117d: 0x3de2, 0x117e: 0x3de6, 0x117f: 0x3dea, + // Block 0x46, offset 0x1180 + 0x1180: 0x3dee, 0x1181: 0x3df2, 0x1182: 0x3df6, 0x1183: 0x3dfa, 0x1184: 0x3dfe, 0x1185: 0x3e02, + 0x1186: 0x3e02, 0x1187: 0x2fba, 0x1188: 0x3e06, 0x1189: 0x3e0a, 0x118a: 0x3e0e, 0x118b: 0x3e12, + 0x118c: 0x2ed1, 0x118d: 0x3e16, 0x118e: 0x3e1a, 0x118f: 0x3e1e, 0x1190: 0x2e39, 0x1191: 0x3e22, + 0x1192: 0x3e26, 0x1193: 0x3e2a, 0x1194: 0x3e2e, 0x1195: 0x3e32, 0x1196: 0x3e36, 0x1197: 0x3e3a, + 0x1198: 0x3e3e, 0x1199: 0x3e42, 0x119a: 0x3e47, 0x119b: 0x3e4b, 0x119c: 0x3e4f, 0x119d: 0x3c55, + 0x119e: 0x3e53, 0x119f: 0x3e57, 0x11a0: 0x3e5b, 0x11a1: 0x3e60, 0x11a2: 0x3e65, 0x11a3: 0x3e69, + 0x11a4: 0x3e6d, 0x11a5: 0x3e71, 0x11a6: 0x3e75, 0x11a7: 0x3e79, 0x11a8: 0x3e7d, 0x11a9: 0x3e81, + 0x11aa: 0x3e85, 0x11ab: 0x3e85, 0x11ac: 0x3e89, 0x11ad: 0x3e8e, 0x11ae: 0x3e92, 0x11af: 0x2be1, + 0x11b0: 0x3e96, 0x11b1: 0x3e9a, 0x11b2: 0x3e9f, 0x11b3: 0x3ea3, 0x11b4: 0x3ea7, 0x11b5: 0x18ce, + 0x11b6: 0x3eab, 0x11b7: 0x3eaf, 0x11b8: 0x18d6, 0x11b9: 0x3eb3, 0x11ba: 0x3eb7, 0x11bb: 0x3ebb, + 0x11bc: 0x3ec0, 0x11bd: 0x3ec4, 0x11be: 0x3ec9, 0x11bf: 0x3ecd, + // Block 0x47, offset 0x11c0 + 0x11c0: 0x3ed1, 0x11c1: 0x3ed5, 0x11c2: 0x3ed9, 0x11c3: 0x3edd, 0x11c4: 0x3ee1, 0x11c5: 0x3ee5, + 0x11c6: 0x3ee9, 0x11c7: 0x3eed, 0x11c8: 0x3ef1, 0x11c9: 0x3ef5, 0x11ca: 0x3efa, 0x11cb: 0x3efe, + 0x11cc: 0x3f02, 0x11cd: 0x3f06, 0x11ce: 0x2b11, 0x11cf: 0x3f0a, 0x11d0: 0x18fe, 0x11d1: 0x3f0f, + 0x11d2: 0x3f0f, 0x11d3: 0x3f14, 0x11d4: 0x3f18, 0x11d5: 0x3f18, 0x11d6: 0x3f1c, 0x11d7: 0x3f20, + 0x11d8: 0x3f25, 0x11d9: 0x3f2a, 0x11da: 0x3f2e, 0x11db: 0x3f32, 0x11dc: 0x3f36, 0x11dd: 0x3f3a, + 0x11de: 0x3f3e, 0x11df: 0x3f42, 0x11e0: 0x3f46, 0x11e1: 0x3f4a, 0x11e2: 0x3f4e, 0x11e3: 0x2ee5, + 0x11e4: 0x3f52, 0x11e5: 0x3f57, 0x11e6: 0x3f5b, 0x11e7: 0x3f5f, 0x11e8: 0x2fea, 0x11e9: 0x3f5f, + 0x11ea: 0x3f63, 0x11eb: 0x2eed, 0x11ec: 0x3f67, 0x11ed: 0x3f6b, 0x11ee: 0x3f6f, 0x11ef: 0x3f73, + 0x11f0: 0x2ef1, 0x11f1: 0x2aa5, 0x11f2: 0x3f77, 0x11f3: 0x3f7b, 0x11f4: 0x3f7f, 0x11f5: 0x3f83, + 0x11f6: 0x3f87, 0x11f7: 0x3f8b, 0x11f8: 0x3f8f, 0x11f9: 0x3f94, 0x11fa: 0x3f98, 0x11fb: 0x3f9c, + 0x11fc: 0x3fa0, 0x11fd: 0x3fa4, 0x11fe: 0x3fa8, 0x11ff: 0x3fad, + // Block 0x48, offset 0x1200 + 0x1200: 0x3fb1, 0x1201: 0x3fb5, 0x1202: 0x3fb9, 0x1203: 0x3fbd, 0x1204: 0x3fc1, 0x1205: 0x3fc5, + 0x1206: 0x3fc9, 0x1207: 0x3fcd, 0x1208: 0x2ef5, 0x1209: 0x3fd1, 0x120a: 0x3fd5, 0x120b: 0x3fda, + 0x120c: 0x3fde, 0x120d: 0x3fe2, 0x120e: 0x3fe6, 0x120f: 0x2efd, 0x1210: 0x3fea, 0x1211: 0x3fee, + 0x1212: 0x3ff2, 0x1213: 0x3ff6, 0x1214: 0x3ffa, 0x1215: 0x3ffe, 0x1216: 0x4002, 0x1217: 0x4006, + 0x1218: 0x2b15, 0x1219: 0x300a, 0x121a: 0x400a, 0x121b: 0x400e, 0x121c: 0x4012, 0x121d: 0x4016, + 0x121e: 0x401b, 0x121f: 0x401f, 0x1220: 0x4023, 0x1221: 0x4027, 0x1222: 0x2f01, 0x1223: 0x402b, + 0x1224: 0x4030, 0x1225: 0x4034, 0x1226: 0x4038, 0x1227: 0x30b5, 0x1228: 0x403c, 0x1229: 0x4040, + 0x122a: 0x4044, 0x122b: 0x4048, 0x122c: 0x404c, 0x122d: 0x4051, 0x122e: 0x4055, 0x122f: 0x4059, + 0x1230: 0x405d, 0x1231: 0x4062, 0x1232: 0x4066, 0x1233: 0x406a, 0x1234: 0x406e, 0x1235: 0x2c25, + 0x1236: 0x4072, 0x1237: 0x4076, 0x1238: 0x407b, 0x1239: 0x4080, 0x123a: 0x4085, 0x123b: 0x4089, + 0x123c: 0x408e, 0x123d: 0x4092, 0x123e: 0x4096, 0x123f: 0x409a, + // Block 0x49, offset 0x1240 + 0x1240: 0x409e, 0x1241: 0x2f05, 0x1242: 0x2d71, 0x1243: 0x40a2, 0x1244: 0x40a6, 0x1245: 0x40aa, + 0x1246: 0x40ae, 0x1247: 0x40b3, 0x1248: 0x40b7, 0x1249: 0x40bb, 0x124a: 0x40bf, 0x124b: 0x3016, + 0x124c: 0x40c3, 0x124d: 0x40c7, 0x124e: 0x40cc, 0x124f: 0x40d0, 0x1250: 0x40d4, 0x1251: 0x40d9, + 0x1252: 0x40de, 0x1253: 0x40e2, 0x1254: 0x301a, 0x1255: 0x40e6, 0x1256: 0x40ea, 0x1257: 0x40ee, + 0x1258: 0x40f2, 0x1259: 0x40f6, 0x125a: 0x40fa, 0x125b: 0x40fe, 0x125c: 0x4103, 0x125d: 0x4107, + 0x125e: 0x410c, 0x125f: 0x4110, 0x1260: 0x4115, 0x1261: 0x3022, 0x1262: 0x4119, 0x1263: 0x411d, + 0x1264: 0x4122, 0x1265: 0x4126, 0x1266: 0x412a, 0x1267: 0x412f, 0x1268: 0x4134, 0x1269: 0x4138, + 0x126a: 0x413c, 0x126b: 0x4140, 0x126c: 0x4144, 0x126d: 0x4144, 0x126e: 0x4148, 0x126f: 0x414c, + 0x1270: 0x302a, 0x1271: 0x4150, 0x1272: 0x4154, 0x1273: 0x4158, 0x1274: 0x415c, 0x1275: 0x4160, + 0x1276: 0x4165, 0x1277: 0x4169, 0x1278: 0x2bed, 0x1279: 0x416e, 0x127a: 0x4173, 0x127b: 0x4177, + 0x127c: 0x417c, 0x127d: 0x4181, 0x127e: 0x4186, 0x127f: 0x418a, + // Block 0x4a, offset 0x1280 + 0x1280: 0x3042, 0x1281: 0x418e, 0x1282: 0x4193, 0x1283: 0x4198, 0x1284: 0x419d, 0x1285: 0x41a2, + 0x1286: 0x41a6, 0x1287: 0x41a6, 0x1288: 0x3046, 0x1289: 0x30bd, 0x128a: 0x41aa, 0x128b: 0x41ae, + 0x128c: 0x41b2, 0x128d: 0x41b6, 0x128e: 0x41bb, 0x128f: 0x2b59, 0x1290: 0x304e, 0x1291: 0x41bf, + 0x1292: 0x41c3, 0x1293: 0x2f2d, 0x1294: 0x41c8, 0x1295: 0x41cd, 0x1296: 0x2e89, 0x1297: 0x41d2, + 0x1298: 0x41d6, 0x1299: 0x2f39, 0x129a: 0x41da, 0x129b: 0x41de, 0x129c: 0x41e2, 0x129d: 0x41e7, + 0x129e: 0x41e7, 0x129f: 0x41ec, 0x12a0: 0x41f0, 0x12a1: 0x41f4, 0x12a2: 0x41f9, 0x12a3: 0x41fd, + 0x12a4: 0x4201, 0x12a5: 0x4205, 0x12a6: 0x420a, 0x12a7: 0x420e, 0x12a8: 0x4212, 0x12a9: 0x4216, + 0x12aa: 0x421a, 0x12ab: 0x421e, 0x12ac: 0x4223, 0x12ad: 0x4227, 0x12ae: 0x422b, 0x12af: 0x422f, + 0x12b0: 0x4233, 0x12b1: 0x4237, 0x12b2: 0x423b, 0x12b3: 0x4240, 0x12b4: 0x4245, 0x12b5: 0x4249, + 0x12b6: 0x424e, 0x12b7: 0x4252, 0x12b8: 0x4257, 0x12b9: 0x425b, 0x12ba: 0x2f51, 0x12bb: 0x425f, + 0x12bc: 0x4264, 0x12bd: 0x4269, 0x12be: 0x426d, 0x12bf: 0x4272, + // Block 0x4b, offset 0x12c0 + 0x12c0: 0x4276, 0x12c1: 0x427b, 0x12c2: 0x427f, 0x12c3: 0x4283, 0x12c4: 0x4287, 0x12c5: 0x428b, + 0x12c6: 0x428f, 0x12c7: 0x4293, 0x12c8: 0x4298, 0x12c9: 0x429d, 0x12ca: 0x42a2, 0x12cb: 0x3f14, + 0x12cc: 0x42a7, 0x12cd: 0x42ab, 0x12ce: 0x42af, 0x12cf: 0x42b3, 0x12d0: 0x42b7, 0x12d1: 0x42bb, + 0x12d2: 0x42bf, 0x12d3: 0x42c3, 0x12d4: 0x42c7, 0x12d5: 0x42cb, 0x12d6: 0x42cf, 0x12d7: 0x42d3, + 0x12d8: 0x2c31, 0x12d9: 0x42d8, 0x12da: 0x42dc, 0x12db: 0x42e0, 0x12dc: 0x42e4, 0x12dd: 0x42e8, + 0x12de: 0x42ec, 0x12df: 0x2f5d, 0x12e0: 0x42f0, 0x12e1: 0x42f4, 0x12e2: 0x42f8, 0x12e3: 0x42fc, + 0x12e4: 0x4300, 0x12e5: 0x4305, 0x12e6: 0x430a, 0x12e7: 0x430f, 0x12e8: 0x4313, 0x12e9: 0x4317, + 0x12ea: 0x431b, 0x12eb: 0x431f, 0x12ec: 0x4324, 0x12ed: 0x4328, 0x12ee: 0x432d, 0x12ef: 0x4331, + 0x12f0: 0x4335, 0x12f1: 0x433a, 0x12f2: 0x433f, 0x12f3: 0x4343, 0x12f4: 0x2b45, 0x12f5: 0x4347, + 0x12f6: 0x434b, 0x12f7: 0x434f, 0x12f8: 0x4353, 0x12f9: 0x4357, 0x12fa: 0x435b, 0x12fb: 0x306a, + 0x12fc: 0x435f, 0x12fd: 0x4363, 0x12fe: 0x4367, 0x12ff: 0x436b, + // Block 0x4c, offset 0x1300 + 0x1300: 0x436f, 0x1301: 0x4373, 0x1302: 0x4377, 0x1303: 0x437b, 0x1304: 0x1a66, 0x1305: 0x437f, + 0x1306: 0x4384, 0x1307: 0x4388, 0x1308: 0x438c, 0x1309: 0x4390, 0x130a: 0x4394, 0x130b: 0x4398, + 0x130c: 0x439d, 0x130d: 0x43a2, 0x130e: 0x43a6, 0x130f: 0x43aa, 0x1310: 0x307e, 0x1311: 0x3082, + 0x1312: 0x1a82, 0x1313: 0x43ae, 0x1314: 0x43b3, 0x1315: 0x43b7, 0x1316: 0x43bb, 0x1317: 0x43bf, + 0x1318: 0x43c3, 0x1319: 0x43c8, 0x131a: 0x43cd, 0x131b: 0x43d1, 0x131c: 0x43d5, 0x131d: 0x43d9, + 0x131e: 0x43de, 0x131f: 0x3086, 0x1320: 0x43e2, 0x1321: 0x43e7, 0x1322: 0x43ec, 0x1323: 0x43f0, + 0x1324: 0x43f4, 0x1325: 0x43f8, 0x1326: 0x43fd, 0x1327: 0x4401, 0x1328: 0x4405, 0x1329: 0x4409, + 0x132a: 0x440d, 0x132b: 0x4411, 0x132c: 0x4415, 0x132d: 0x4419, 0x132e: 0x441e, 0x132f: 0x4422, + 0x1330: 0x4426, 0x1331: 0x442a, 0x1332: 0x442f, 0x1333: 0x4433, 0x1334: 0x4437, 0x1335: 0x443b, + 0x1336: 0x443f, 0x1337: 0x4444, 0x1338: 0x4449, 0x1339: 0x444d, 0x133a: 0x4451, 0x133b: 0x4455, + 0x133c: 0x445a, 0x133d: 0x445e, 0x133e: 0x309e, 0x133f: 0x309e, + // Block 0x4d, offset 0x1340 + 0x1340: 0x4463, 0x1341: 0x4467, 0x1342: 0x446c, 0x1343: 0x4470, 0x1344: 0x4474, 0x1345: 0x4478, + 0x1346: 0x447c, 0x1347: 0x4480, 0x1348: 0x4484, 0x1349: 0x4488, 0x134a: 0x30a2, 0x134b: 0x448d, + 0x134c: 0x4491, 0x134d: 0x4495, 0x134e: 0x4499, 0x134f: 0x449d, 0x1350: 0x44a1, 0x1351: 0x44a6, + 0x1352: 0x44aa, 0x1353: 0x44af, 0x1354: 0x44b4, 0x1355: 0x1b42, 0x1356: 0x44b9, 0x1357: 0x1b52, + 0x1358: 0x44bd, 0x1359: 0x44c1, 0x135a: 0x44c5, 0x135b: 0x44c9, 0x135c: 0x1b66, 0x135d: 0x44cd, +} + +// nfcDecompLookup: 832 bytes +// Block 0 is the null block. +var nfcDecompLookup = [832]uint8{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0x0c3: 0x03, 0x0c4: 0x04, 0x0c5: 0x05, 0x0c6: 0x06, 0x0c7: 0x07, + 0x0c8: 0x08, 0x0cd: 0x09, 0x0ce: 0x0a, 0x0cf: 0x0b, + 0x0d0: 0x0c, 0x0d1: 0x0d, 0x0d3: 0x0e, + 0x0d8: 0x0f, 0x0db: 0x10, + 0x0e0: 0x04, 0x0e1: 0x05, 0x0e2: 0x06, 0x0e3: 0x07, + 0x0ef: 0x08, + 0x0f0: 0x0c, + // Block 0x4, offset 0x100 + 0x124: 0x11, 0x125: 0x12, 0x127: 0x13, + 0x128: 0x14, 0x129: 0x15, 0x12d: 0x16, 0x12e: 0x17, 0x12f: 0x18, + 0x131: 0x19, 0x133: 0x1a, 0x135: 0x1b, 0x137: 0x1c, + 0x13d: 0x1d, 0x13e: 0x1e, + // Block 0x5, offset 0x140 + 0x140: 0x1f, + 0x16c: 0x20, 0x16d: 0x21, + 0x178: 0x22, 0x179: 0x23, 0x17a: 0x24, 0x17b: 0x25, 0x17c: 0x26, 0x17d: 0x27, 0x17e: 0x28, 0x17f: 0x29, + // Block 0x6, offset 0x180 + 0x180: 0x2a, 0x184: 0x2b, 0x186: 0x2c, 0x187: 0x2d, + 0x188: 0x2e, 0x189: 0x2f, 0x18a: 0x30, 0x18b: 0x31, 0x18c: 0x32, + 0x1ab: 0x33, + // Block 0x7, offset 0x1c0 + 0x1c1: 0x34, 0x1c2: 0x35, 0x1c3: 0x36, + // Block 0x8, offset 0x200 + 0x224: 0x37, 0x225: 0x38, 0x226: 0x39, 0x227: 0x3a, + 0x228: 0x3b, 0x229: 0x3c, 0x22a: 0x3d, 0x22b: 0x3e, 0x22c: 0x3f, 0x22d: 0x40, + // Block 0x9, offset 0x240 + 0x242: 0x41, + // Block 0xa, offset 0x280 + 0x285: 0x42, 0x286: 0x43, 0x287: 0x44, + // Block 0xb, offset 0x2c0 + 0x2e0: 0x45, 0x2e1: 0x46, 0x2e2: 0x47, 0x2e3: 0x48, 0x2e4: 0x49, 0x2e5: 0x4a, 0x2e6: 0x4b, 0x2e7: 0x4c, + 0x2e8: 0x4d, + // Block 0xc, offset 0x300 + 0x311: 0x09, + 0x31d: 0x0a, + 0x32f: 0x0b, +} + +var nfcDecompTrie = trie{nfcDecompLookup[:], nfcDecompValues[:]} + +// nfkcDecompValues: 10176 entries, 20352 bytes +// Block 2 is the null block. +var nfkcDecompValues = [10176]uint16{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0x00e0: 0x0001, + 0x00e8: 0x0003, + 0x00ea: 0x0007, 0x00ef: 0x0009, + 0x00f2: 0x000d, 0x00f3: 0x000f, 0x00f4: 0x0011, 0x00f5: 0x0015, + 0x00f8: 0x0018, 0x00f9: 0x001c, 0x00fa: 0x001e, + 0x00fc: 0x0020, 0x00fd: 0x0026, 0x00fe: 0x002c, + // Block 0x4, offset 0x100 + 0x0100: 0x0032, 0x0101: 0x0036, 0x0102: 0x003a, 0x0103: 0x003e, 0x0104: 0x0042, 0x0105: 0x0046, + 0x0107: 0x004a, 0x0108: 0x004e, 0x0109: 0x0052, 0x010a: 0x0056, 0x010b: 0x005a, + 0x010c: 0x005e, 0x010d: 0x0062, 0x010e: 0x0066, 0x010f: 0x006a, 0x0111: 0x006e, + 0x0112: 0x0072, 0x0113: 0x0076, 0x0114: 0x007a, 0x0115: 0x007e, 0x0116: 0x0082, + 0x0119: 0x0086, 0x011a: 0x008a, 0x011b: 0x008e, 0x011c: 0x0092, 0x011d: 0x0096, + 0x0120: 0x009a, 0x0121: 0x009e, 0x0122: 0x00a2, 0x0123: 0x00a6, + 0x0124: 0x00aa, 0x0125: 0x00ae, 0x0127: 0x00b2, 0x0128: 0x00b6, 0x0129: 0x00ba, + 0x012a: 0x00be, 0x012b: 0x00c2, 0x012c: 0x00c6, 0x012d: 0x00ca, 0x012e: 0x00ce, 0x012f: 0x00d2, + 0x0131: 0x00d6, 0x0132: 0x00da, 0x0133: 0x00de, 0x0134: 0x00e2, 0x0135: 0x00e6, + 0x0136: 0x00ea, 0x0139: 0x00ee, 0x013a: 0x00f2, 0x013b: 0x00f6, + 0x013c: 0x00fa, 0x013d: 0x00fe, 0x013f: 0x0102, + // Block 0x5, offset 0x140 + 0x0140: 0x0106, 0x0141: 0x010a, 0x0142: 0x010e, 0x0143: 0x0112, 0x0144: 0x0116, 0x0145: 0x011a, + 0x0146: 0x011e, 0x0147: 0x0122, 0x0148: 0x0126, 0x0149: 0x012a, 0x014a: 0x012e, 0x014b: 0x0132, + 0x014c: 0x0136, 0x014d: 0x013a, 0x014e: 0x013e, 0x014f: 0x0142, + 0x0152: 0x0146, 0x0153: 0x014a, 0x0154: 0x014e, 0x0155: 0x0152, 0x0156: 0x0156, 0x0157: 0x015a, + 0x0158: 0x015e, 0x0159: 0x0162, 0x015a: 0x0166, 0x015b: 0x016a, 0x015c: 0x016e, 0x015d: 0x0172, + 0x015e: 0x0176, 0x015f: 0x017a, 0x0160: 0x017e, 0x0161: 0x0182, 0x0162: 0x0186, 0x0163: 0x018a, + 0x0164: 0x018e, 0x0165: 0x0192, 0x0168: 0x0196, 0x0169: 0x019a, + 0x016a: 0x019e, 0x016b: 0x01a2, 0x016c: 0x01a6, 0x016d: 0x01aa, 0x016e: 0x01ae, 0x016f: 0x01b2, + 0x0170: 0x01b6, 0x0172: 0x01ba, 0x0173: 0x01bd, 0x0174: 0x01c0, 0x0175: 0x01c4, + 0x0176: 0x01c8, 0x0177: 0x01cc, 0x0179: 0x01d0, 0x017a: 0x01d4, 0x017b: 0x01d8, + 0x017c: 0x01dc, 0x017d: 0x01e0, 0x017e: 0x01e4, 0x017f: 0x01e8, + // Block 0x6, offset 0x180 + 0x0180: 0x01ec, 0x0183: 0x01f0, 0x0184: 0x01f4, 0x0185: 0x01f8, + 0x0186: 0x01fc, 0x0187: 0x0200, 0x0188: 0x0204, 0x0189: 0x0208, + 0x018c: 0x020c, 0x018d: 0x0210, 0x018e: 0x0214, 0x018f: 0x0218, 0x0190: 0x021c, 0x0191: 0x0220, + 0x0194: 0x0224, 0x0195: 0x0228, 0x0196: 0x022c, 0x0197: 0x0230, + 0x0198: 0x0234, 0x0199: 0x0238, 0x019a: 0x023c, 0x019b: 0x0240, 0x019c: 0x0244, 0x019d: 0x0248, + 0x019e: 0x024c, 0x019f: 0x0250, 0x01a0: 0x0254, 0x01a1: 0x0258, 0x01a2: 0x025c, 0x01a3: 0x0260, + 0x01a4: 0x0264, 0x01a5: 0x0268, 0x01a8: 0x026c, 0x01a9: 0x0270, + 0x01aa: 0x0274, 0x01ab: 0x0278, 0x01ac: 0x027c, 0x01ad: 0x0280, 0x01ae: 0x0284, 0x01af: 0x0288, + 0x01b0: 0x028c, 0x01b1: 0x0290, 0x01b2: 0x0294, 0x01b3: 0x0298, 0x01b4: 0x029c, 0x01b5: 0x02a0, + 0x01b6: 0x02a4, 0x01b7: 0x02a8, 0x01b8: 0x02ac, 0x01b9: 0x02b0, 0x01ba: 0x02b4, 0x01bb: 0x02b8, + 0x01bc: 0x02bc, 0x01bd: 0x02c0, 0x01be: 0x02c4, 0x01bf: 0x02c8, + // Block 0x7, offset 0x1c0 + 0x01e0: 0x02ca, 0x01e1: 0x02ce, + 0x01ef: 0x02d2, + 0x01f0: 0x02d6, + // Block 0x8, offset 0x200 + 0x0204: 0x02da, 0x0205: 0x02df, + 0x0206: 0x02e4, 0x0207: 0x02e9, 0x0208: 0x02ec, 0x0209: 0x02ef, 0x020a: 0x02f2, 0x020b: 0x02f5, + 0x020c: 0x02f8, 0x020d: 0x02fb, 0x020e: 0x02ff, 0x020f: 0x0303, 0x0210: 0x0307, 0x0211: 0x030b, + 0x0212: 0x030f, 0x0213: 0x0313, 0x0214: 0x0317, 0x0215: 0x031b, 0x0216: 0x0321, 0x0217: 0x0327, + 0x0218: 0x032d, 0x0219: 0x0333, 0x021a: 0x0339, 0x021b: 0x033f, 0x021c: 0x0345, + 0x021e: 0x034b, 0x021f: 0x0351, 0x0220: 0x0357, 0x0221: 0x035d, 0x0222: 0x0363, 0x0223: 0x0368, + 0x0226: 0x036d, 0x0227: 0x0371, 0x0228: 0x0375, 0x0229: 0x0379, + 0x022a: 0x037d, 0x022b: 0x0381, 0x022c: 0x0385, 0x022d: 0x038b, 0x022e: 0x0391, 0x022f: 0x0396, + 0x0230: 0x039b, 0x0231: 0x039f, 0x0232: 0x03a2, 0x0233: 0x03a5, 0x0234: 0x03a8, 0x0235: 0x03ac, + 0x0238: 0x03b0, 0x0239: 0x03b4, 0x023a: 0x03b8, 0x023b: 0x03be, + 0x023c: 0x03c4, 0x023d: 0x03c9, 0x023e: 0x03ce, 0x023f: 0x03d3, + // Block 0x9, offset 0x240 + 0x0240: 0x03d8, 0x0241: 0x03dc, 0x0242: 0x03e0, 0x0243: 0x03e4, 0x0244: 0x03e8, 0x0245: 0x03ec, + 0x0246: 0x03f0, 0x0247: 0x03f4, 0x0248: 0x03f8, 0x0249: 0x03fc, 0x024a: 0x0400, 0x024b: 0x0404, + 0x024c: 0x0408, 0x024d: 0x040c, 0x024e: 0x0410, 0x024f: 0x0414, 0x0250: 0x0418, 0x0251: 0x041c, + 0x0252: 0x0420, 0x0253: 0x0424, 0x0254: 0x0428, 0x0255: 0x042c, 0x0256: 0x0430, 0x0257: 0x0434, + 0x0258: 0x0438, 0x0259: 0x043c, 0x025a: 0x0440, 0x025b: 0x0444, + 0x025e: 0x0448, 0x025f: 0x044c, + 0x0266: 0x0450, 0x0267: 0x0454, 0x0268: 0x0458, 0x0269: 0x045c, + 0x026a: 0x0460, 0x026b: 0x0466, 0x026c: 0x046c, 0x026d: 0x0472, 0x026e: 0x0478, 0x026f: 0x047c, + 0x0270: 0x0480, 0x0271: 0x0486, 0x0272: 0x048c, 0x0273: 0x0490, + // Block 0xa, offset 0x280 + 0x02b0: 0x0494, 0x02b1: 0x0496, 0x02b2: 0x0499, 0x02b3: 0x049b, 0x02b4: 0x049d, 0x02b5: 0x04a0, + 0x02b6: 0x04a3, 0x02b7: 0x04a6, 0x02b8: 0x04a8, + // Block 0xb, offset 0x2c0 + 0x02d8: 0x04aa, 0x02d9: 0x04ae, 0x02da: 0x04b2, 0x02db: 0x04b6, 0x02dc: 0x04ba, 0x02dd: 0x04be, + 0x02e0: 0x04c2, 0x02e1: 0x04c5, 0x02e2: 0x02c8, 0x02e3: 0x04c7, + 0x02e4: 0x04c9, + // Block 0xc, offset 0x300 + 0x0300: 0x04cc, 0x0301: 0x04cf, 0x0303: 0x04d2, 0x0304: 0x04d5, + 0x0334: 0x04da, + 0x033a: 0x04dd, + 0x033e: 0x04e1, + // Block 0xd, offset 0x340 + 0x0344: 0x0011, 0x0345: 0x04e8, + 0x0346: 0x04ee, 0x0347: 0x04f3, 0x0348: 0x04f6, 0x0349: 0x04fb, 0x034a: 0x0500, + 0x034c: 0x0505, 0x034e: 0x050a, 0x034f: 0x050f, 0x0350: 0x0514, + 0x036a: 0x051b, 0x036b: 0x0520, 0x036c: 0x0525, 0x036d: 0x052a, 0x036e: 0x052f, 0x036f: 0x0534, + 0x0370: 0x0539, + // Block 0xe, offset 0x380 + 0x038a: 0x0540, 0x038b: 0x0545, + 0x038c: 0x054a, 0x038d: 0x054f, 0x038e: 0x0554, 0x0390: 0x0559, 0x0391: 0x055c, + 0x0392: 0x055f, 0x0393: 0x050a, 0x0394: 0x0520, 0x0395: 0x056c, 0x0396: 0x056f, + 0x03b0: 0x0572, 0x03b1: 0x0575, 0x03b2: 0x0578, 0x03b4: 0x057b, 0x03b5: 0x057e, + 0x03b9: 0x0581, + // Block 0xf, offset 0x3c0 + 0x03c0: 0x0584, 0x03c1: 0x0589, 0x03c3: 0x058e, + 0x03c7: 0x0593, + 0x03cc: 0x0598, 0x03cd: 0x059d, 0x03ce: 0x05a2, + 0x03d9: 0x05a7, + 0x03f9: 0x05ac, + // Block 0x10, offset 0x400 + 0x0410: 0x05b1, 0x0411: 0x05b6, + 0x0413: 0x05bb, 0x0417: 0x05c0, + 0x041c: 0x05c5, 0x041d: 0x05ca, + 0x041e: 0x05cf, + 0x0436: 0x05d4, 0x0437: 0x05d9, + // Block 0x11, offset 0x440 + 0x0441: 0x05de, 0x0442: 0x05e3, + 0x0450: 0x05e8, 0x0451: 0x05ed, + 0x0452: 0x05f2, 0x0453: 0x05f7, 0x0456: 0x05fc, 0x0457: 0x0601, + 0x045a: 0x0606, 0x045b: 0x060b, 0x045c: 0x0610, 0x045d: 0x0615, + 0x045e: 0x061a, 0x045f: 0x061f, 0x0462: 0x0624, 0x0463: 0x0629, + 0x0464: 0x062e, 0x0465: 0x0633, 0x0466: 0x0638, 0x0467: 0x063d, + 0x046a: 0x0642, 0x046b: 0x0647, 0x046c: 0x064c, 0x046d: 0x0651, 0x046e: 0x0656, 0x046f: 0x065b, + 0x0470: 0x0660, 0x0471: 0x0665, 0x0472: 0x066a, 0x0473: 0x066f, 0x0474: 0x0674, 0x0475: 0x0679, + 0x0478: 0x067e, 0x0479: 0x0683, + // Block 0x12, offset 0x480 + 0x0487: 0x0688, + // Block 0x13, offset 0x4c0 + 0x04e2: 0x068d, 0x04e3: 0x0692, + 0x04e4: 0x0697, 0x04e5: 0x069c, 0x04e6: 0x06a1, + // Block 0x14, offset 0x500 + 0x0535: 0x06a6, + 0x0536: 0x06ab, 0x0537: 0x06b0, 0x0538: 0x06b5, + // Block 0x15, offset 0x540 + 0x0540: 0x06ba, 0x0542: 0x06bf, + 0x0553: 0x06c4, + // Block 0x16, offset 0x580 + 0x05a9: 0x06c9, + 0x05b1: 0x06d0, 0x05b4: 0x06d7, + // Block 0x17, offset 0x5c0 + 0x05d8: 0x06de, 0x05d9: 0x06e5, 0x05da: 0x06ec, 0x05db: 0x06f3, 0x05dc: 0x06fa, 0x05dd: 0x0701, + 0x05de: 0x0708, 0x05df: 0x070f, + // Block 0x18, offset 0x600 + 0x060b: 0x0716, + 0x060c: 0x071d, + 0x061c: 0x0724, 0x061d: 0x072b, + 0x061f: 0x0732, + // Block 0x19, offset 0x640 + 0x0673: 0x0739, + 0x0676: 0x0740, + // Block 0x1a, offset 0x680 + 0x0699: 0x0747, 0x069a: 0x074e, 0x069b: 0x0755, + 0x069e: 0x075c, + // Block 0x1b, offset 0x6c0 + 0x06c8: 0x0763, 0x06cb: 0x076a, + 0x06cc: 0x0771, + 0x06dc: 0x0778, 0x06dd: 0x077f, + // Block 0x1c, offset 0x700 + 0x0714: 0x0786, + // Block 0x1d, offset 0x740 + 0x074a: 0x078d, 0x074b: 0x0794, + 0x074c: 0x079b, + // Block 0x1e, offset 0x780 + 0x0788: 0x07a2, + // Block 0x1f, offset 0x7c0 + 0x07c0: 0x07a9, + 0x07c7: 0x07b0, 0x07c8: 0x07b7, 0x07ca: 0x07be, 0x07cb: 0x07c5, + // Block 0x20, offset 0x800 + 0x080a: 0x07cf, 0x080b: 0x07d6, + 0x080c: 0x07dd, + // Block 0x21, offset 0x840 + 0x085a: 0x07e4, 0x085c: 0x07eb, 0x085d: 0x07f2, + 0x085e: 0x07fc, + // Block 0x22, offset 0x880 + 0x08b3: 0x0803, + // Block 0x23, offset 0x8c0 + 0x08f3: 0x080a, + // Block 0x24, offset 0x900 + 0x091c: 0x0811, 0x091d: 0x0818, + // Block 0x25, offset 0x940 + 0x094c: 0x081f, + // Block 0x26, offset 0x980 + 0x0983: 0x0823, + 0x098d: 0x082a, + 0x0992: 0x0831, 0x0997: 0x0838, + 0x099c: 0x083f, + 0x09a9: 0x0846, + 0x09b3: 0x084d, 0x09b5: 0x0854, + 0x09b6: 0x085b, 0x09b7: 0x0862, 0x09b8: 0x086c, 0x09b9: 0x0873, + // Block 0x27, offset 0x9c0 + 0x09c1: 0x087d, + 0x09d3: 0x0884, + 0x09dd: 0x088b, + 0x09e2: 0x0892, + 0x09e7: 0x0899, + 0x09ec: 0x08a0, + 0x09f9: 0x08a7, + // Block 0x28, offset 0xa00 + 0x0a26: 0x08ae, + // Block 0x29, offset 0xa40 + 0x0a7c: 0x08b5, + // Block 0x2a, offset 0xa80 + 0x0a86: 0x08b9, 0x0a88: 0x08c0, 0x0a8a: 0x08c7, + 0x0a8c: 0x08ce, 0x0a8e: 0x08d5, + 0x0a92: 0x08dc, + 0x0abb: 0x08e3, + 0x0abd: 0x08ea, + // Block 0x2b, offset 0xac0 + 0x0ac0: 0x08f1, 0x0ac1: 0x08f8, 0x0ac3: 0x08ff, + // Block 0x2c, offset 0xb00 + 0x0b2c: 0x0906, 0x0b2d: 0x0908, 0x0b2e: 0x090b, + 0x0b30: 0x090d, 0x0b31: 0x090f, 0x0b32: 0x0911, 0x0b33: 0x0914, 0x0b34: 0x0916, 0x0b35: 0x0918, + 0x0b36: 0x091a, 0x0b37: 0x091c, 0x0b38: 0x091e, 0x0b39: 0x0920, 0x0b3a: 0x0922, + 0x0b3c: 0x0924, 0x0b3d: 0x0926, 0x0b3e: 0x0929, 0x0b3f: 0x092b, + // Block 0x2d, offset 0xb40 + 0x0b40: 0x092d, 0x0b41: 0x092f, 0x0b42: 0x0931, 0x0b43: 0x0007, 0x0b44: 0x0933, 0x0b45: 0x0936, + 0x0b46: 0x0939, 0x0b47: 0x093d, 0x0b48: 0x093f, 0x0b49: 0x0941, 0x0b4a: 0x0943, 0x0b4b: 0x0946, + 0x0b4c: 0x0949, 0x0b4d: 0x094c, 0x0b4f: 0x094e, 0x0b50: 0x0950, 0x0b51: 0x0952, + 0x0b52: 0x001e, 0x0b53: 0x0955, 0x0b54: 0x0958, 0x0b55: 0x095c, 0x0b56: 0x0960, 0x0b57: 0x0962, + 0x0b58: 0x0964, 0x0b59: 0x0966, 0x0b5a: 0x096a, 0x0b5b: 0x096d, 0x0b5c: 0x096f, 0x0b5d: 0x0559, + 0x0b5e: 0x0973, 0x0b5f: 0x0976, 0x0b60: 0x056c, 0x0b61: 0x0979, 0x0b62: 0x097c, 0x0b63: 0x049b, + 0x0b64: 0x0964, 0x0b65: 0x096d, 0x0b66: 0x0559, 0x0b67: 0x0973, 0x0b68: 0x0575, 0x0b69: 0x056c, + 0x0b6a: 0x0979, + 0x0b78: 0x097e, + // Block 0x2e, offset 0xb80 + 0x0b9b: 0x0981, 0x0b9c: 0x0984, 0x0b9d: 0x0986, + 0x0b9e: 0x0989, 0x0b9f: 0x0949, 0x0ba0: 0x098c, 0x0ba1: 0x098e, 0x0ba2: 0x0991, 0x0ba3: 0x0994, + 0x0ba4: 0x0997, 0x0ba5: 0x099a, 0x0ba6: 0x099d, 0x0ba7: 0x09a0, 0x0ba8: 0x09a4, 0x0ba9: 0x09a7, + 0x0baa: 0x09aa, 0x0bab: 0x09ae, 0x0bac: 0x09b1, 0x0bad: 0x09b4, 0x0bae: 0x09b7, 0x0baf: 0x09ba, + 0x0bb0: 0x09bd, 0x0bb1: 0x09c0, 0x0bb2: 0x09c3, 0x0bb3: 0x09c6, 0x0bb4: 0x09c9, 0x0bb5: 0x09cc, + 0x0bb6: 0x09cf, 0x0bb7: 0x09d2, 0x0bb8: 0x09d5, 0x0bb9: 0x09d9, 0x0bba: 0x09dc, 0x0bbb: 0x09df, + 0x0bbc: 0x09e1, 0x0bbd: 0x09e4, 0x0bbe: 0x09e7, 0x0bbf: 0x055c, + // Block 0x2f, offset 0xbc0 + 0x0bc0: 0x09ea, 0x0bc1: 0x09ee, 0x0bc2: 0x09f2, 0x0bc3: 0x09f6, 0x0bc4: 0x09fa, 0x0bc5: 0x09fe, + 0x0bc6: 0x0a02, 0x0bc7: 0x0a06, 0x0bc8: 0x0a0a, 0x0bc9: 0x0a10, 0x0bca: 0x0a16, 0x0bcb: 0x0a1a, + 0x0bcc: 0x0a1e, 0x0bcd: 0x0a22, 0x0bce: 0x0a26, 0x0bcf: 0x0a2a, 0x0bd0: 0x0a2e, 0x0bd1: 0x0a32, + 0x0bd2: 0x0a36, 0x0bd3: 0x0a3a, 0x0bd4: 0x0a3e, 0x0bd5: 0x0a44, 0x0bd6: 0x0a4a, 0x0bd7: 0x0a50, + 0x0bd8: 0x0a56, 0x0bd9: 0x0a5a, 0x0bda: 0x0a5e, 0x0bdb: 0x0a62, 0x0bdc: 0x0a66, 0x0bdd: 0x0a6c, + 0x0bde: 0x0a72, 0x0bdf: 0x0a76, 0x0be0: 0x0a7a, 0x0be1: 0x0a7e, 0x0be2: 0x0a82, 0x0be3: 0x0a86, + 0x0be4: 0x0a8a, 0x0be5: 0x0a8e, 0x0be6: 0x0a92, 0x0be7: 0x0a96, 0x0be8: 0x0a9a, 0x0be9: 0x0a9e, + 0x0bea: 0x0aa2, 0x0beb: 0x0aa6, 0x0bec: 0x0aaa, 0x0bed: 0x0aae, 0x0bee: 0x0ab2, 0x0bef: 0x0ab8, + 0x0bf0: 0x0abe, 0x0bf1: 0x0ac2, 0x0bf2: 0x0ac6, 0x0bf3: 0x0aca, 0x0bf4: 0x0ace, 0x0bf5: 0x0ad2, + 0x0bf6: 0x0ad6, 0x0bf7: 0x0ada, 0x0bf8: 0x0ade, 0x0bf9: 0x0ae4, 0x0bfa: 0x0aea, 0x0bfb: 0x0aee, + 0x0bfc: 0x0af2, 0x0bfd: 0x0af6, 0x0bfe: 0x0afa, 0x0bff: 0x0afe, + // Block 0x30, offset 0xc00 + 0x0c00: 0x0b02, 0x0c01: 0x0b06, 0x0c02: 0x0b0a, 0x0c03: 0x0b0e, 0x0c04: 0x0b12, 0x0c05: 0x0b16, + 0x0c06: 0x0b1a, 0x0c07: 0x0b1e, 0x0c08: 0x0b22, 0x0c09: 0x0b26, 0x0c0a: 0x0b2a, 0x0c0b: 0x0b2e, + 0x0c0c: 0x0b32, 0x0c0d: 0x0b38, 0x0c0e: 0x0b3e, 0x0c0f: 0x0b44, 0x0c10: 0x0b4a, 0x0c11: 0x0b50, + 0x0c12: 0x0b56, 0x0c13: 0x0b5c, 0x0c14: 0x0b62, 0x0c15: 0x0b66, 0x0c16: 0x0b6a, 0x0c17: 0x0b6e, + 0x0c18: 0x0b72, 0x0c19: 0x0b76, 0x0c1a: 0x0b7a, 0x0c1b: 0x0b7e, 0x0c1c: 0x0b82, 0x0c1d: 0x0b88, + 0x0c1e: 0x0b8e, 0x0c1f: 0x0b92, 0x0c20: 0x0b96, 0x0c21: 0x0b9a, 0x0c22: 0x0b9e, 0x0c23: 0x0ba2, + 0x0c24: 0x0ba6, 0x0c25: 0x0bac, 0x0c26: 0x0bb2, 0x0c27: 0x0bb8, 0x0c28: 0x0bbe, 0x0c29: 0x0bc4, + 0x0c2a: 0x0bca, 0x0c2b: 0x0bce, 0x0c2c: 0x0bd2, 0x0c2d: 0x0bd6, 0x0c2e: 0x0bda, 0x0c2f: 0x0bde, + 0x0c30: 0x0be2, 0x0c31: 0x0be6, 0x0c32: 0x0bea, 0x0c33: 0x0bee, 0x0c34: 0x0bf2, 0x0c35: 0x0bf6, + 0x0c36: 0x0bfa, 0x0c37: 0x0bfe, 0x0c38: 0x0c02, 0x0c39: 0x0c08, 0x0c3a: 0x0c0e, 0x0c3b: 0x0c14, + 0x0c3c: 0x0c1a, 0x0c3d: 0x0c1e, 0x0c3e: 0x0c22, 0x0c3f: 0x0c26, + // Block 0x31, offset 0xc40 + 0x0c40: 0x0c2a, 0x0c41: 0x0c2e, 0x0c42: 0x0c32, 0x0c43: 0x0c36, 0x0c44: 0x0c3a, 0x0c45: 0x0c3e, + 0x0c46: 0x0c42, 0x0c47: 0x0c46, 0x0c48: 0x0c4a, 0x0c49: 0x0c4e, 0x0c4a: 0x0c52, 0x0c4b: 0x0c56, + 0x0c4c: 0x0c5a, 0x0c4d: 0x0c5e, 0x0c4e: 0x0c62, 0x0c4f: 0x0c66, 0x0c50: 0x0c6a, 0x0c51: 0x0c6e, + 0x0c52: 0x0c72, 0x0c53: 0x0c76, 0x0c54: 0x0c7a, 0x0c55: 0x0c7e, 0x0c56: 0x0c82, 0x0c57: 0x0c86, + 0x0c58: 0x0c8a, 0x0c59: 0x0c8e, 0x0c5a: 0x0c92, 0x0c5b: 0x0b9a, + 0x0c60: 0x0c9b, 0x0c61: 0x0c9f, 0x0c62: 0x0ca3, 0x0c63: 0x0ca7, + 0x0c64: 0x0cab, 0x0c65: 0x0cb1, 0x0c66: 0x0cb7, 0x0c67: 0x0cbd, 0x0c68: 0x0cc3, 0x0c69: 0x0cc9, + 0x0c6a: 0x0ccf, 0x0c6b: 0x0cd5, 0x0c6c: 0x0cdb, 0x0c6d: 0x0ce1, 0x0c6e: 0x0ce7, 0x0c6f: 0x0ced, + 0x0c70: 0x0cf3, 0x0c71: 0x0cf9, 0x0c72: 0x0cff, 0x0c73: 0x0d05, 0x0c74: 0x0d0b, 0x0c75: 0x0d11, + 0x0c76: 0x0d17, 0x0c77: 0x0d1d, 0x0c78: 0x0d23, 0x0c79: 0x0d27, 0x0c7a: 0x0d2b, 0x0c7b: 0x0d2f, + 0x0c7c: 0x0d33, 0x0c7d: 0x0d37, 0x0c7e: 0x0d3b, 0x0c7f: 0x0d41, + // Block 0x32, offset 0xc80 + 0x0c80: 0x0d47, 0x0c81: 0x0d4d, 0x0c82: 0x0d53, 0x0c83: 0x0d59, 0x0c84: 0x0d5f, 0x0c85: 0x0d65, + 0x0c86: 0x0d6b, 0x0c87: 0x0d71, 0x0c88: 0x0d77, 0x0c89: 0x0d7b, 0x0c8a: 0x0d7f, 0x0c8b: 0x0d83, + 0x0c8c: 0x0d87, 0x0c8d: 0x0d8b, 0x0c8e: 0x0d8f, 0x0c8f: 0x0d93, 0x0c90: 0x0d97, 0x0c91: 0x0d9d, + 0x0c92: 0x0da3, 0x0c93: 0x0da9, 0x0c94: 0x0daf, 0x0c95: 0x0db5, 0x0c96: 0x0dbb, 0x0c97: 0x0dc1, + 0x0c98: 0x0dc7, 0x0c99: 0x0dcd, 0x0c9a: 0x0dd3, 0x0c9b: 0x0dd9, 0x0c9c: 0x0ddf, 0x0c9d: 0x0de5, + 0x0c9e: 0x0deb, 0x0c9f: 0x0df1, 0x0ca0: 0x0df7, 0x0ca1: 0x0dfd, 0x0ca2: 0x0e03, 0x0ca3: 0x0e09, + 0x0ca4: 0x0e0f, 0x0ca5: 0x0e13, 0x0ca6: 0x0e17, 0x0ca7: 0x0e1b, 0x0ca8: 0x0e1f, 0x0ca9: 0x0e25, + 0x0caa: 0x0e2b, 0x0cab: 0x0e31, 0x0cac: 0x0e37, 0x0cad: 0x0e3d, 0x0cae: 0x0e43, 0x0caf: 0x0e49, + 0x0cb0: 0x0e4f, 0x0cb1: 0x0e55, 0x0cb2: 0x0e5b, 0x0cb3: 0x0e5f, 0x0cb4: 0x0e63, 0x0cb5: 0x0e67, + 0x0cb6: 0x0e6b, 0x0cb7: 0x0e6f, 0x0cb8: 0x0e73, 0x0cb9: 0x0e77, + // Block 0x33, offset 0xcc0 + 0x0cc0: 0x0e7b, 0x0cc1: 0x0e80, 0x0cc2: 0x0e85, 0x0cc3: 0x0e8c, 0x0cc4: 0x0e93, 0x0cc5: 0x0e9a, + 0x0cc6: 0x0ea1, 0x0cc7: 0x0ea8, 0x0cc8: 0x0eaf, 0x0cc9: 0x0eb4, 0x0cca: 0x0eb9, 0x0ccb: 0x0ec0, + 0x0ccc: 0x0ec7, 0x0ccd: 0x0ece, 0x0cce: 0x0ed5, 0x0ccf: 0x0edc, 0x0cd0: 0x0ee3, 0x0cd1: 0x0ee8, + 0x0cd2: 0x0eed, 0x0cd3: 0x0ef4, 0x0cd4: 0x0efb, 0x0cd5: 0x0f02, + 0x0cd8: 0x0f09, 0x0cd9: 0x0f0e, 0x0cda: 0x0f13, 0x0cdb: 0x0f1a, 0x0cdc: 0x0f21, 0x0cdd: 0x0f28, + 0x0ce0: 0x0f2f, 0x0ce1: 0x0f34, 0x0ce2: 0x0f39, 0x0ce3: 0x0f40, + 0x0ce4: 0x0f47, 0x0ce5: 0x0f4e, 0x0ce6: 0x0f55, 0x0ce7: 0x0f5c, 0x0ce8: 0x0f63, 0x0ce9: 0x0f68, + 0x0cea: 0x0f6d, 0x0ceb: 0x0f74, 0x0cec: 0x0f7b, 0x0ced: 0x0f82, 0x0cee: 0x0f89, 0x0cef: 0x0f90, + 0x0cf0: 0x0f97, 0x0cf1: 0x0f9c, 0x0cf2: 0x0fa1, 0x0cf3: 0x0fa8, 0x0cf4: 0x0faf, 0x0cf5: 0x0fb6, + 0x0cf6: 0x0fbd, 0x0cf7: 0x0fc4, 0x0cf8: 0x0fcb, 0x0cf9: 0x0fd0, 0x0cfa: 0x0fd5, 0x0cfb: 0x0fdc, + 0x0cfc: 0x0fe3, 0x0cfd: 0x0fea, 0x0cfe: 0x0ff1, 0x0cff: 0x0ff8, + // Block 0x34, offset 0xd00 + 0x0d00: 0x0fff, 0x0d01: 0x1004, 0x0d02: 0x1009, 0x0d03: 0x1010, 0x0d04: 0x1017, 0x0d05: 0x101e, + 0x0d08: 0x1025, 0x0d09: 0x102a, 0x0d0a: 0x102f, 0x0d0b: 0x1036, + 0x0d0c: 0x103d, 0x0d0d: 0x1044, 0x0d10: 0x104b, 0x0d11: 0x1050, + 0x0d12: 0x1055, 0x0d13: 0x105c, 0x0d14: 0x1063, 0x0d15: 0x106a, 0x0d16: 0x1071, 0x0d17: 0x1078, + 0x0d19: 0x107f, 0x0d1b: 0x1084, 0x0d1d: 0x108b, + 0x0d1f: 0x1092, 0x0d20: 0x1099, 0x0d21: 0x109e, 0x0d22: 0x10a3, 0x0d23: 0x10aa, + 0x0d24: 0x10b1, 0x0d25: 0x10b8, 0x0d26: 0x10bf, 0x0d27: 0x10c6, 0x0d28: 0x10cd, 0x0d29: 0x10d2, + 0x0d2a: 0x10d7, 0x0d2b: 0x10de, 0x0d2c: 0x10e5, 0x0d2d: 0x10ec, 0x0d2e: 0x10f3, 0x0d2f: 0x10fa, + 0x0d30: 0x1101, 0x0d31: 0x0525, 0x0d32: 0x1106, 0x0d33: 0x052a, 0x0d34: 0x110b, 0x0d35: 0x052f, + 0x0d36: 0x1110, 0x0d37: 0x0534, 0x0d38: 0x1115, 0x0d39: 0x054a, 0x0d3a: 0x111a, 0x0d3b: 0x054f, + 0x0d3c: 0x111f, 0x0d3d: 0x0554, + // Block 0x35, offset 0xd40 + 0x0d40: 0x1124, 0x0d41: 0x112b, 0x0d42: 0x1132, 0x0d43: 0x113b, 0x0d44: 0x1144, 0x0d45: 0x114d, + 0x0d46: 0x1156, 0x0d47: 0x115f, 0x0d48: 0x1168, 0x0d49: 0x116f, 0x0d4a: 0x1176, 0x0d4b: 0x117f, + 0x0d4c: 0x1188, 0x0d4d: 0x1191, 0x0d4e: 0x119a, 0x0d4f: 0x11a3, 0x0d50: 0x11ac, 0x0d51: 0x11b3, + 0x0d52: 0x11ba, 0x0d53: 0x11c3, 0x0d54: 0x11cc, 0x0d55: 0x11d5, 0x0d56: 0x11de, 0x0d57: 0x11e7, + 0x0d58: 0x11f0, 0x0d59: 0x11f7, 0x0d5a: 0x11fe, 0x0d5b: 0x1207, 0x0d5c: 0x1210, 0x0d5d: 0x1219, + 0x0d5e: 0x1222, 0x0d5f: 0x122b, 0x0d60: 0x1234, 0x0d61: 0x123b, 0x0d62: 0x1242, 0x0d63: 0x124b, + 0x0d64: 0x1254, 0x0d65: 0x125d, 0x0d66: 0x1266, 0x0d67: 0x126f, 0x0d68: 0x1278, 0x0d69: 0x127f, + 0x0d6a: 0x1286, 0x0d6b: 0x128f, 0x0d6c: 0x1298, 0x0d6d: 0x12a1, 0x0d6e: 0x12aa, 0x0d6f: 0x12b3, + 0x0d70: 0x12bc, 0x0d71: 0x12c1, 0x0d72: 0x12c6, 0x0d73: 0x12cd, 0x0d74: 0x12d2, + 0x0d76: 0x12d9, 0x0d77: 0x12de, 0x0d78: 0x12e5, 0x0d79: 0x12ea, 0x0d7a: 0x12ef, 0x0d7b: 0x04ee, + 0x0d7c: 0x12f4, 0x0d7d: 0x12f9, 0x0d7e: 0x12fd, 0x0d7f: 0x12f9, + // Block 0x36, offset 0xd80 + 0x0d80: 0x1300, 0x0d81: 0x1309, 0x0d82: 0x130f, 0x0d83: 0x1316, 0x0d84: 0x131b, + 0x0d86: 0x1322, 0x0d87: 0x1327, 0x0d88: 0x132e, 0x0d89: 0x04f6, 0x0d8a: 0x1333, 0x0d8b: 0x04fb, + 0x0d8c: 0x1338, 0x0d8d: 0x1343, 0x0d8e: 0x134f, 0x0d8f: 0x135b, 0x0d90: 0x1361, 0x0d91: 0x1366, + 0x0d92: 0x136b, 0x0d93: 0x0514, 0x0d96: 0x1372, 0x0d97: 0x1377, + 0x0d98: 0x137e, 0x0d99: 0x1383, 0x0d9a: 0x1388, 0x0d9b: 0x0500, 0x0d9d: 0x1393, + 0x0d9e: 0x139f, 0x0d9f: 0x13ab, 0x0da0: 0x13b1, 0x0da1: 0x13b6, 0x0da2: 0x13bb, 0x0da3: 0x0539, + 0x0da4: 0x13c2, 0x0da5: 0x13c7, 0x0da6: 0x13cc, 0x0da7: 0x13d1, 0x0da8: 0x13d8, 0x0da9: 0x13dd, + 0x0daa: 0x13e2, 0x0dab: 0x050a, 0x0dac: 0x13e7, 0x0dad: 0x13f1, 0x0dae: 0x04e8, 0x0daf: 0x13f7, + 0x0db2: 0x13f9, 0x0db3: 0x1400, 0x0db4: 0x1405, + 0x0db6: 0x140c, 0x0db7: 0x1411, 0x0db8: 0x1418, 0x0db9: 0x0505, 0x0dba: 0x141d, 0x0dbb: 0x050f, + 0x0dbc: 0x1422, 0x0dbd: 0x0011, 0x0dbe: 0x142a, + // Block 0x37, offset 0xdc0 + 0x0dc0: 0x0001, 0x0dc1: 0x0001, 0x0dc2: 0x0001, 0x0dc3: 0x0001, 0x0dc4: 0x0001, 0x0dc5: 0x0001, + 0x0dc6: 0x0001, 0x0dc7: 0x0001, 0x0dc8: 0x0001, 0x0dc9: 0x0001, 0x0dca: 0x0001, + 0x0dd1: 0x1436, + 0x0dd7: 0x143a, + 0x0de4: 0x143e, 0x0de5: 0x1440, 0x0de6: 0x1443, + 0x0def: 0x0001, + 0x0df3: 0x1447, 0x0df4: 0x144e, + 0x0df6: 0x1458, 0x0df7: 0x145f, + 0x0dfc: 0x1469, 0x0dfe: 0x146c, + // Block 0x38, offset 0xe00 + 0x0e07: 0x1470, 0x0e08: 0x1473, 0x0e09: 0x1476, + 0x0e17: 0x1479, + 0x0e1f: 0x0001, + 0x0e30: 0x1486, 0x0e31: 0x097c, 0x0e34: 0x1488, 0x0e35: 0x148a, + 0x0e36: 0x148c, 0x0e37: 0x148e, 0x0e38: 0x1490, 0x0e39: 0x1492, 0x0e3a: 0x1494, 0x0e3b: 0x1496, + 0x0e3c: 0x149a, 0x0e3d: 0x149c, 0x0e3e: 0x149e, 0x0e3f: 0x14a0, + // Block 0x39, offset 0xe40 + 0x0e40: 0x1486, 0x0e41: 0x001c, 0x0e42: 0x000d, 0x0e43: 0x000f, 0x0e44: 0x1488, 0x0e45: 0x148a, + 0x0e46: 0x148c, 0x0e47: 0x148e, 0x0e48: 0x1490, 0x0e49: 0x1492, 0x0e4a: 0x1494, 0x0e4b: 0x1496, + 0x0e4c: 0x149a, 0x0e4d: 0x149c, 0x0e4e: 0x149e, 0x0e50: 0x0007, 0x0e51: 0x0941, + 0x0e52: 0x001e, 0x0e53: 0x04c7, 0x0e54: 0x0943, 0x0e55: 0x0494, 0x0e56: 0x094e, 0x0e57: 0x04c5, + 0x0e58: 0x0950, 0x0e59: 0x14a0, 0x0e5a: 0x0960, 0x0e5b: 0x02c8, 0x0e5c: 0x0962, + 0x0e68: 0x14a2, + // Block 0x3a, offset 0xe80 + 0x0e80: 0x14a5, 0x0e81: 0x14a9, 0x0e82: 0x14ad, 0x0e83: 0x14af, 0x0e85: 0x14b3, + 0x0e86: 0x14b7, 0x0e87: 0x14bb, 0x0e89: 0x14be, 0x0e8a: 0x094c, 0x0e8b: 0x0916, + 0x0e8c: 0x0916, 0x0e8d: 0x0916, 0x0e8e: 0x0494, 0x0e8f: 0x14c2, 0x0e90: 0x0918, 0x0e91: 0x0918, + 0x0e92: 0x091e, 0x0e93: 0x04c5, 0x0e95: 0x0922, 0x0e96: 0x14c5, + 0x0e99: 0x0929, 0x0e9a: 0x14c8, 0x0e9b: 0x092b, 0x0e9c: 0x092b, 0x0e9d: 0x092b, + 0x0ea0: 0x14ca, 0x0ea1: 0x14cd, 0x0ea2: 0x14d1, + 0x0ea4: 0x14d4, 0x0ea6: 0x14d6, 0x0ea8: 0x14d4, + 0x0eaa: 0x091c, 0x0eab: 0x0046, 0x0eac: 0x090b, 0x0ead: 0x14ad, 0x0eaf: 0x0941, + 0x0eb0: 0x090f, 0x0eb1: 0x14d9, 0x0eb3: 0x0920, 0x0eb4: 0x001e, 0x0eb5: 0x14db, + 0x0eb6: 0x14de, 0x0eb7: 0x14e1, 0x0eb8: 0x14e4, 0x0eb9: 0x097c, 0x0ebb: 0x14e7, + 0x0ebc: 0x056f, 0x0ebd: 0x0973, 0x0ebe: 0x14eb, 0x0ebf: 0x14ee, + // Block 0x3b, offset 0xec0 + 0x0ec0: 0x14f1, 0x0ec5: 0x090d, + 0x0ec6: 0x093f, 0x0ec7: 0x0941, 0x0ec8: 0x097c, 0x0ec9: 0x0499, + 0x0ed0: 0x14f5, 0x0ed1: 0x14fb, + 0x0ed2: 0x1501, 0x0ed3: 0x1508, 0x0ed4: 0x150e, 0x0ed5: 0x1514, 0x0ed6: 0x151a, 0x0ed7: 0x1520, + 0x0ed8: 0x1526, 0x0ed9: 0x152c, 0x0eda: 0x1532, 0x0edb: 0x1538, 0x0edc: 0x153e, 0x0edd: 0x1544, + 0x0ede: 0x154a, 0x0edf: 0x1550, 0x0ee0: 0x0918, 0x0ee1: 0x1555, 0x0ee2: 0x1558, 0x0ee3: 0x155c, + 0x0ee4: 0x155f, 0x0ee5: 0x1561, 0x0ee6: 0x1564, 0x0ee7: 0x1568, 0x0ee8: 0x156d, 0x0ee9: 0x1570, + 0x0eea: 0x1572, 0x0eeb: 0x1575, 0x0eec: 0x091e, 0x0eed: 0x14ad, 0x0eee: 0x090d, 0x0eef: 0x0920, + 0x0ef0: 0x097c, 0x0ef1: 0x1579, 0x0ef2: 0x157c, 0x0ef3: 0x1580, 0x0ef4: 0x096d, 0x0ef5: 0x1583, + 0x0ef6: 0x1586, 0x0ef7: 0x158a, 0x0ef8: 0x158f, 0x0ef9: 0x04c7, 0x0efa: 0x1592, 0x0efb: 0x1595, + 0x0efc: 0x04c5, 0x0efd: 0x0984, 0x0efe: 0x093f, 0x0eff: 0x0950, + // Block 0x3c, offset 0xf00 + 0x0f09: 0x1599, + 0x0f1a: 0x159f, 0x0f1b: 0x15a5, + 0x0f2e: 0x15ab, + // Block 0x3d, offset 0xf40 + 0x0f4d: 0x15b1, 0x0f4e: 0x15b7, 0x0f4f: 0x15bd, + // Block 0x3e, offset 0xf80 + 0x0f84: 0x15c3, + 0x0f89: 0x15c9, + 0x0f8c: 0x15cf, + 0x0fa4: 0x15d5, 0x0fa6: 0x15db, + 0x0fac: 0x15e1, 0x0fad: 0x15e8, 0x0faf: 0x15f2, + 0x0fb0: 0x15f9, + // Block 0x3f, offset 0xfc0 + 0x0fc1: 0x1603, 0x0fc4: 0x1609, + 0x0fc7: 0x160f, 0x0fc9: 0x1615, + 0x0fe0: 0x161b, 0x0fe2: 0x161f, + 0x0fed: 0x1625, 0x0fee: 0x162b, 0x0fef: 0x162f, + 0x0ff0: 0x1633, 0x0ff1: 0x1639, 0x0ff4: 0x163f, 0x0ff5: 0x1645, + 0x0ff8: 0x164b, 0x0ff9: 0x1651, + // Block 0x40, offset 0x1000 + 0x1000: 0x1657, 0x1001: 0x165d, 0x1004: 0x1663, 0x1005: 0x1669, + 0x1008: 0x166f, 0x1009: 0x1675, + 0x102c: 0x167b, 0x102d: 0x1681, 0x102e: 0x1687, 0x102f: 0x168d, + // Block 0x41, offset 0x1040 + 0x1060: 0x1693, 0x1061: 0x1699, 0x1062: 0x169f, 0x1063: 0x16a5, + 0x106a: 0x16ab, 0x106b: 0x16b1, 0x106c: 0x16b7, 0x106d: 0x16bd, + // Block 0x42, offset 0x1080 + 0x10a9: 0x16c3, + 0x10aa: 0x16c7, + // Block 0x43, offset 0x10c0 + 0x10e0: 0x001c, 0x10e1: 0x000d, 0x10e2: 0x000f, 0x10e3: 0x1488, + 0x10e4: 0x148a, 0x10e5: 0x148c, 0x10e6: 0x148e, 0x10e7: 0x1490, 0x10e8: 0x1492, 0x10e9: 0x16cb, + 0x10ea: 0x16ce, 0x10eb: 0x16d1, 0x10ec: 0x16d4, 0x10ed: 0x16d7, 0x10ee: 0x16da, 0x10ef: 0x16dd, + 0x10f0: 0x16e0, 0x10f1: 0x16e3, 0x10f2: 0x16e6, 0x10f3: 0x16e9, 0x10f4: 0x16ec, 0x10f5: 0x16f0, + 0x10f6: 0x16f4, 0x10f7: 0x16f8, 0x10f8: 0x16fc, 0x10f9: 0x1700, 0x10fa: 0x1704, 0x10fb: 0x1708, + 0x10fc: 0x170c, 0x10fd: 0x1710, 0x10fe: 0x1715, 0x10ff: 0x171a, + // Block 0x44, offset 0x1100 + 0x1100: 0x171f, 0x1101: 0x1724, 0x1102: 0x1729, 0x1103: 0x172e, 0x1104: 0x1733, 0x1105: 0x1738, + 0x1106: 0x173d, 0x1107: 0x1742, 0x1108: 0x1747, 0x1109: 0x174a, 0x110a: 0x174d, 0x110b: 0x1750, + 0x110c: 0x1753, 0x110d: 0x1756, 0x110e: 0x1759, 0x110f: 0x175c, 0x1110: 0x175f, 0x1111: 0x1762, + 0x1112: 0x1766, 0x1113: 0x176a, 0x1114: 0x176e, 0x1115: 0x1772, 0x1116: 0x1776, 0x1117: 0x177a, + 0x1118: 0x177e, 0x1119: 0x1782, 0x111a: 0x1786, 0x111b: 0x178a, 0x111c: 0x178e, 0x111d: 0x1792, + 0x111e: 0x1796, 0x111f: 0x179a, 0x1120: 0x179e, 0x1121: 0x17a2, 0x1122: 0x17a6, 0x1123: 0x17aa, + 0x1124: 0x17ae, 0x1125: 0x17b2, 0x1126: 0x17b6, 0x1127: 0x17ba, 0x1128: 0x17be, 0x1129: 0x17c2, + 0x112a: 0x17c6, 0x112b: 0x17ca, 0x112c: 0x17ce, 0x112d: 0x17d2, 0x112e: 0x17d6, 0x112f: 0x17da, + 0x1130: 0x17de, 0x1131: 0x17e2, 0x1132: 0x17e6, 0x1133: 0x17ea, 0x1134: 0x17ee, 0x1135: 0x17f2, + 0x1136: 0x0906, 0x1137: 0x090b, 0x1138: 0x14ad, 0x1139: 0x090d, 0x113a: 0x090f, 0x113b: 0x14d9, + 0x113c: 0x0914, 0x113d: 0x0916, 0x113e: 0x0918, 0x113f: 0x091a, + // Block 0x45, offset 0x1140 + 0x1140: 0x091c, 0x1141: 0x091e, 0x1142: 0x0920, 0x1143: 0x0922, 0x1144: 0x0924, 0x1145: 0x0929, + 0x1146: 0x14c8, 0x1147: 0x092b, 0x1148: 0x17f6, 0x1149: 0x092d, 0x114a: 0x092f, 0x114b: 0x155f, + 0x114c: 0x0931, 0x114d: 0x1570, 0x114e: 0x17f8, 0x114f: 0x14d4, 0x1150: 0x0007, 0x1151: 0x093d, + 0x1152: 0x0984, 0x1153: 0x093f, 0x1154: 0x0941, 0x1155: 0x098c, 0x1156: 0x094c, 0x1157: 0x0494, + 0x1158: 0x097c, 0x1159: 0x0499, 0x115a: 0x094e, 0x115b: 0x04c5, 0x115c: 0x0950, 0x115d: 0x14a0, + 0x115e: 0x001e, 0x115f: 0x0960, 0x1160: 0x17fa, 0x1161: 0x049b, 0x1162: 0x02c8, 0x1163: 0x0962, + 0x1164: 0x0964, 0x1165: 0x096d, 0x1166: 0x04a6, 0x1167: 0x04c7, 0x1168: 0x04a8, 0x1169: 0x09df, + 0x116a: 0x1486, + // Block 0x46, offset 0x1180 + 0x118c: 0x17fc, + // Block 0x47, offset 0x11c0 + 0x11f4: 0x1809, 0x11f5: 0x180d, + 0x11f6: 0x1810, + // Block 0x48, offset 0x1200 + 0x121c: 0x1814, + // Block 0x49, offset 0x1240 + 0x127c: 0x0499, 0x127d: 0x155f, + // Block 0x4a, offset 0x1280 + 0x12af: 0x181a, + // Block 0x4b, offset 0x12c0 + 0x12df: 0x181e, + // Block 0x4c, offset 0x1300 + 0x1333: 0x1822, + // Block 0x4d, offset 0x1340 + 0x1340: 0x1826, 0x1341: 0x182a, 0x1342: 0x182e, 0x1343: 0x1832, 0x1344: 0x1836, 0x1345: 0x183a, + 0x1346: 0x183e, 0x1347: 0x1842, 0x1348: 0x1846, 0x1349: 0x184a, 0x134a: 0x184e, 0x134b: 0x1852, + 0x134c: 0x1856, 0x134d: 0x185a, 0x134e: 0x185e, 0x134f: 0x1862, 0x1350: 0x1866, 0x1351: 0x186a, + 0x1352: 0x186e, 0x1353: 0x1872, 0x1354: 0x1876, 0x1355: 0x187a, 0x1356: 0x187e, 0x1357: 0x1882, + 0x1358: 0x1886, 0x1359: 0x188a, 0x135a: 0x188e, 0x135b: 0x1892, 0x135c: 0x1896, 0x135d: 0x189a, + 0x135e: 0x189e, 0x135f: 0x18a2, 0x1360: 0x18a6, 0x1361: 0x18aa, 0x1362: 0x18ae, 0x1363: 0x18b2, + 0x1364: 0x18b6, 0x1365: 0x18ba, 0x1366: 0x18be, 0x1367: 0x18c2, 0x1368: 0x18c6, 0x1369: 0x18ca, + 0x136a: 0x18ce, 0x136b: 0x18d2, 0x136c: 0x18d6, 0x136d: 0x18da, 0x136e: 0x18de, 0x136f: 0x18e2, + 0x1370: 0x18e6, 0x1371: 0x18ea, 0x1372: 0x18ee, 0x1373: 0x18f2, 0x1374: 0x18f6, 0x1375: 0x18fa, + 0x1376: 0x18fe, 0x1377: 0x1902, 0x1378: 0x1906, 0x1379: 0x190a, 0x137a: 0x190e, 0x137b: 0x1912, + 0x137c: 0x1916, 0x137d: 0x191a, 0x137e: 0x191e, 0x137f: 0x1922, + // Block 0x4e, offset 0x1380 + 0x1380: 0x1926, 0x1381: 0x192a, 0x1382: 0x192e, 0x1383: 0x1932, 0x1384: 0x1936, 0x1385: 0x193a, + 0x1386: 0x193e, 0x1387: 0x1942, 0x1388: 0x1946, 0x1389: 0x194a, 0x138a: 0x194e, 0x138b: 0x1952, + 0x138c: 0x1956, 0x138d: 0x195a, 0x138e: 0x195e, 0x138f: 0x1962, 0x1390: 0x1966, 0x1391: 0x196a, + 0x1392: 0x196e, 0x1393: 0x1972, 0x1394: 0x1976, 0x1395: 0x197a, 0x1396: 0x197e, 0x1397: 0x1982, + 0x1398: 0x1986, 0x1399: 0x198a, 0x139a: 0x198e, 0x139b: 0x1992, 0x139c: 0x1996, 0x139d: 0x199a, + 0x139e: 0x199e, 0x139f: 0x19a2, 0x13a0: 0x19a6, 0x13a1: 0x19aa, 0x13a2: 0x19ae, 0x13a3: 0x19b2, + 0x13a4: 0x19b6, 0x13a5: 0x19ba, 0x13a6: 0x19be, 0x13a7: 0x19c2, 0x13a8: 0x19c6, 0x13a9: 0x19ca, + 0x13aa: 0x19ce, 0x13ab: 0x19d2, 0x13ac: 0x19d6, 0x13ad: 0x19da, 0x13ae: 0x19de, 0x13af: 0x19e2, + 0x13b0: 0x19e6, 0x13b1: 0x19ea, 0x13b2: 0x19ee, 0x13b3: 0x19f2, 0x13b4: 0x19f6, 0x13b5: 0x19fa, + 0x13b6: 0x19fe, 0x13b7: 0x1a02, 0x13b8: 0x1a06, 0x13b9: 0x1a0a, 0x13ba: 0x1a0e, 0x13bb: 0x1a12, + 0x13bc: 0x1a16, 0x13bd: 0x1a1a, 0x13be: 0x1a1e, 0x13bf: 0x1a22, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x1a26, 0x13c1: 0x1a2a, 0x13c2: 0x1a2e, 0x13c3: 0x1a32, 0x13c4: 0x1a36, 0x13c5: 0x1a3a, + 0x13c6: 0x1a3e, 0x13c7: 0x1a42, 0x13c8: 0x1a46, 0x13c9: 0x1a4a, 0x13ca: 0x1a4e, 0x13cb: 0x1a52, + 0x13cc: 0x1a56, 0x13cd: 0x1a5a, 0x13ce: 0x1a5e, 0x13cf: 0x1a62, 0x13d0: 0x1a66, 0x13d1: 0x1a6a, + 0x13d2: 0x1a6e, 0x13d3: 0x1a72, 0x13d4: 0x1a76, 0x13d5: 0x1a7a, 0x13d6: 0x1a7e, 0x13d7: 0x1a82, + 0x13d8: 0x1a86, 0x13d9: 0x1a8a, 0x13da: 0x1a8e, 0x13db: 0x1a92, 0x13dc: 0x1a96, 0x13dd: 0x1a9a, + 0x13de: 0x1a9e, 0x13df: 0x1aa2, 0x13e0: 0x1aa6, 0x13e1: 0x1aaa, 0x13e2: 0x1aae, 0x13e3: 0x1ab2, + 0x13e4: 0x1ab6, 0x13e5: 0x1aba, 0x13e6: 0x1abe, 0x13e7: 0x1ac2, 0x13e8: 0x1ac6, 0x13e9: 0x1aca, + 0x13ea: 0x1ace, 0x13eb: 0x1ad2, 0x13ec: 0x1ad6, 0x13ed: 0x1ada, 0x13ee: 0x1ade, 0x13ef: 0x1ae2, + 0x13f0: 0x1ae6, 0x13f1: 0x1aea, 0x13f2: 0x1aee, 0x13f3: 0x1af2, 0x13f4: 0x1af6, 0x13f5: 0x1afa, + 0x13f6: 0x1afe, 0x13f7: 0x1b02, 0x13f8: 0x1b06, 0x13f9: 0x1b0a, 0x13fa: 0x1b0e, 0x13fb: 0x1b12, + 0x13fc: 0x1b16, 0x13fd: 0x1b1a, 0x13fe: 0x1b1e, 0x13ff: 0x1b22, + // Block 0x50, offset 0x1400 + 0x1400: 0x1b26, 0x1401: 0x1b2a, 0x1402: 0x1b2e, 0x1403: 0x1b32, 0x1404: 0x1b36, 0x1405: 0x1b3a, + 0x1406: 0x1b3e, 0x1407: 0x1b42, 0x1408: 0x1b46, 0x1409: 0x1b4a, 0x140a: 0x1b4e, 0x140b: 0x1b52, + 0x140c: 0x1b56, 0x140d: 0x1b5a, 0x140e: 0x1b5e, 0x140f: 0x1b62, 0x1410: 0x1b66, 0x1411: 0x1b6a, + 0x1412: 0x1b6e, 0x1413: 0x1b72, 0x1414: 0x1b76, 0x1415: 0x1b7a, + // Block 0x51, offset 0x1440 + 0x1440: 0x0001, + 0x1476: 0x1b7e, 0x1478: 0x1882, 0x1479: 0x1b82, 0x147a: 0x1b86, + // Block 0x52, offset 0x1480 + 0x148c: 0x1b8a, 0x148e: 0x1b91, 0x1490: 0x1b98, + 0x1492: 0x1b9f, 0x1494: 0x1ba6, 0x1496: 0x1bad, + 0x1498: 0x1bb4, 0x149a: 0x1bbb, 0x149c: 0x1bc2, + 0x149e: 0x1bc9, 0x14a0: 0x1bd0, 0x14a2: 0x1bd7, + 0x14a5: 0x1bde, 0x14a7: 0x1be5, 0x14a9: 0x1bec, + 0x14b0: 0x1bf3, 0x14b1: 0x1bfa, 0x14b3: 0x1c01, 0x14b4: 0x1c08, + 0x14b6: 0x1c0f, 0x14b7: 0x1c16, 0x14b9: 0x1c1d, 0x14ba: 0x1c24, + 0x14bc: 0x1c2b, 0x14bd: 0x1c32, + // Block 0x53, offset 0x14c0 + 0x14d4: 0x1c39, + 0x14db: 0x1c40, 0x14dc: 0x1c45, + 0x14de: 0x1c4a, 0x14df: 0x1c51, + 0x14ec: 0x1c58, 0x14ee: 0x1c5f, + 0x14f0: 0x1c66, 0x14f2: 0x1c6d, 0x14f4: 0x1c74, + 0x14f6: 0x1c7b, 0x14f8: 0x1c82, 0x14fa: 0x1c89, + 0x14fc: 0x1c90, 0x14fe: 0x1c97, + // Block 0x54, offset 0x1500 + 0x1500: 0x1c9e, 0x1502: 0x1ca5, 0x1505: 0x1cac, + 0x1507: 0x1cb3, 0x1509: 0x1cba, + 0x1510: 0x1cc1, 0x1511: 0x1cc8, + 0x1513: 0x1ccf, 0x1514: 0x1cd6, 0x1516: 0x1cdd, 0x1517: 0x1ce4, + 0x1519: 0x1ceb, 0x151a: 0x1cf2, 0x151c: 0x1cf9, 0x151d: 0x1d00, + 0x1534: 0x1d07, + 0x1537: 0x1d0e, 0x1538: 0x1d15, 0x1539: 0x1d1c, 0x153a: 0x1d23, + 0x153e: 0x1d2a, 0x153f: 0x1d31, + // Block 0x55, offset 0x1540 + 0x1571: 0x1d38, 0x1572: 0x1d3c, 0x1573: 0x1d40, 0x1574: 0x1d44, 0x1575: 0x1d48, + 0x1576: 0x1d4c, 0x1577: 0x1d50, 0x1578: 0x1d54, 0x1579: 0x1d58, 0x157a: 0x1d5c, 0x157b: 0x1d60, + 0x157c: 0x1d64, 0x157d: 0x1d68, 0x157e: 0x1d6c, 0x157f: 0x1d70, + // Block 0x56, offset 0x1580 + 0x1580: 0x1d74, 0x1581: 0x1d78, 0x1582: 0x1d7c, 0x1583: 0x1d80, 0x1584: 0x1d84, 0x1585: 0x1d88, + 0x1586: 0x1d8c, 0x1587: 0x1d90, 0x1588: 0x1d94, 0x1589: 0x1d98, 0x158a: 0x1d9c, 0x158b: 0x1da0, + 0x158c: 0x1da4, 0x158d: 0x1da8, 0x158e: 0x1dac, 0x158f: 0x1db0, 0x1590: 0x1db4, 0x1591: 0x1db8, + 0x1592: 0x1dbc, 0x1593: 0x1dc0, 0x1594: 0x1dc4, 0x1595: 0x1dc8, 0x1596: 0x1dcc, 0x1597: 0x1dd0, + 0x1598: 0x1dd4, 0x1599: 0x1dd8, 0x159a: 0x1ddc, 0x159b: 0x1de0, 0x159c: 0x1de4, 0x159d: 0x1de8, + 0x159e: 0x1dec, 0x159f: 0x1df0, 0x15a0: 0x1df4, 0x15a1: 0x1df8, 0x15a2: 0x1dfc, 0x15a3: 0x1e00, + 0x15a4: 0x1e04, 0x15a5: 0x1e08, 0x15a6: 0x1e0c, 0x15a7: 0x1e10, 0x15a8: 0x1e14, 0x15a9: 0x1e18, + 0x15aa: 0x1e1c, 0x15ab: 0x1e20, 0x15ac: 0x1e24, 0x15ad: 0x1e28, 0x15ae: 0x1e2c, 0x15af: 0x1e30, + 0x15b0: 0x1e34, 0x15b1: 0x1e38, 0x15b2: 0x1e3c, 0x15b3: 0x1e40, 0x15b4: 0x1e44, 0x15b5: 0x1e48, + 0x15b6: 0x1e4c, 0x15b7: 0x1e50, 0x15b8: 0x1e54, 0x15b9: 0x1e58, 0x15ba: 0x1e5c, 0x15bb: 0x1e60, + 0x15bc: 0x1e64, 0x15bd: 0x1e68, 0x15be: 0x1e6c, 0x15bf: 0x1e70, + // Block 0x57, offset 0x15c0 + 0x15c0: 0x1e74, 0x15c1: 0x1e78, 0x15c2: 0x1e7c, 0x15c3: 0x1e80, 0x15c4: 0x1e84, 0x15c5: 0x1e88, + 0x15c6: 0x1e8c, 0x15c7: 0x1e90, 0x15c8: 0x1e94, 0x15c9: 0x1e98, 0x15ca: 0x1e9c, 0x15cb: 0x1ea0, + 0x15cc: 0x1ea4, 0x15cd: 0x1ea8, 0x15ce: 0x1eac, + 0x15d2: 0x1826, 0x15d3: 0x183e, 0x15d4: 0x1eb0, 0x15d5: 0x1eb4, 0x15d6: 0x1eb8, 0x15d7: 0x1ebc, + 0x15d8: 0x1ec0, 0x15d9: 0x1ec4, 0x15da: 0x1836, 0x15db: 0x1ec8, 0x15dc: 0x1ecc, 0x15dd: 0x1ed0, + 0x15de: 0x1ed4, 0x15df: 0x1846, + // Block 0x58, offset 0x1600 + 0x1600: 0x1ed8, 0x1601: 0x1ede, 0x1602: 0x1ee4, 0x1603: 0x1eea, 0x1604: 0x1ef0, 0x1605: 0x1ef6, + 0x1606: 0x1efc, 0x1607: 0x1f02, 0x1608: 0x1f08, 0x1609: 0x1f0e, 0x160a: 0x1f14, 0x160b: 0x1f1a, + 0x160c: 0x1f20, 0x160d: 0x1f26, 0x160e: 0x1f2c, 0x160f: 0x1f35, 0x1610: 0x1f3e, 0x1611: 0x1f47, + 0x1612: 0x1f50, 0x1613: 0x1f59, 0x1614: 0x1f62, 0x1615: 0x1f6b, 0x1616: 0x1f74, 0x1617: 0x1f7d, + 0x1618: 0x1f86, 0x1619: 0x1f8f, 0x161a: 0x1f98, 0x161b: 0x1fa1, 0x161c: 0x1faa, 0x161d: 0x1fb3, + 0x161e: 0x1fc5, 0x1620: 0x1fd4, 0x1621: 0x1fda, 0x1622: 0x1fe0, 0x1623: 0x1fe6, + 0x1624: 0x1fec, 0x1625: 0x1ff2, 0x1626: 0x1ff8, 0x1627: 0x1ffe, 0x1628: 0x2004, 0x1629: 0x200a, + 0x162a: 0x2010, 0x162b: 0x2016, 0x162c: 0x201c, 0x162d: 0x2022, 0x162e: 0x2028, 0x162f: 0x202e, + 0x1630: 0x2034, 0x1631: 0x203a, 0x1632: 0x2040, 0x1633: 0x2046, 0x1634: 0x204c, 0x1635: 0x2052, + 0x1636: 0x2058, 0x1637: 0x205e, 0x1638: 0x2064, 0x1639: 0x206a, 0x163a: 0x2070, 0x163b: 0x2076, + 0x163c: 0x207c, 0x163d: 0x2082, 0x163e: 0x2088, 0x163f: 0x208e, + // Block 0x59, offset 0x1640 + 0x1640: 0x2094, 0x1641: 0x209a, 0x1642: 0x20a0, 0x1643: 0x20a6, 0x1644: 0x20ac, 0x1645: 0x20b0, + 0x1646: 0x192e, 0x1647: 0x20b4, + 0x1650: 0x20b8, 0x1651: 0x20bc, + 0x1652: 0x20bf, 0x1653: 0x20c2, 0x1654: 0x20c5, 0x1655: 0x20c8, 0x1656: 0x20cb, 0x1657: 0x20ce, + 0x1658: 0x20d1, 0x1659: 0x20d4, 0x165a: 0x20d7, 0x165b: 0x20da, 0x165c: 0x20dd, 0x165d: 0x20e0, + 0x165e: 0x20e3, 0x165f: 0x20e6, 0x1660: 0x1d38, 0x1661: 0x1d44, 0x1662: 0x1d50, 0x1663: 0x1d58, + 0x1664: 0x1d78, 0x1665: 0x1d7c, 0x1666: 0x1d88, 0x1667: 0x1d90, 0x1668: 0x1d94, 0x1669: 0x1d9c, + 0x166a: 0x1da0, 0x166b: 0x1da4, 0x166c: 0x1da8, 0x166d: 0x1dac, 0x166e: 0x20e9, 0x166f: 0x20f0, + 0x1670: 0x20f7, 0x1671: 0x20fe, 0x1672: 0x2105, 0x1673: 0x210c, 0x1674: 0x2113, 0x1675: 0x211a, + 0x1676: 0x2121, 0x1677: 0x2128, 0x1678: 0x212f, 0x1679: 0x2136, 0x167a: 0x213d, 0x167b: 0x2144, + 0x167c: 0x214b, 0x167d: 0x215b, 0x167e: 0x2168, + // Block 0x5a, offset 0x1680 + 0x1680: 0x1826, 0x1681: 0x183e, 0x1682: 0x1eb0, 0x1683: 0x1eb4, 0x1684: 0x216f, 0x1685: 0x2173, + 0x1686: 0x2177, 0x1687: 0x1852, 0x1688: 0x217b, 0x1689: 0x1882, 0x168a: 0x194a, 0x168b: 0x197a, + 0x168c: 0x1976, 0x168d: 0x194e, 0x168e: 0x1abe, 0x168f: 0x18a2, 0x1690: 0x1942, 0x1691: 0x217f, + 0x1692: 0x2183, 0x1693: 0x2187, 0x1694: 0x218b, 0x1695: 0x218f, 0x1696: 0x2193, 0x1697: 0x2197, + 0x1698: 0x219b, 0x1699: 0x219f, 0x169a: 0x21a3, 0x169b: 0x18ba, 0x169c: 0x21a7, 0x169d: 0x21ab, + 0x169e: 0x21af, 0x169f: 0x21b3, 0x16a0: 0x21b7, 0x16a1: 0x21bb, 0x16a2: 0x21bf, 0x16a3: 0x21c3, + 0x16a4: 0x1eb8, 0x16a5: 0x1ebc, 0x16a6: 0x1ec0, 0x16a7: 0x21c7, 0x16a8: 0x21cb, 0x16a9: 0x21cf, + 0x16aa: 0x21d3, 0x16ab: 0x21d7, 0x16ac: 0x21db, 0x16ad: 0x21df, 0x16ae: 0x21e3, 0x16af: 0x21e7, + 0x16b0: 0x21eb, 0x16b1: 0x21ef, 0x16b2: 0x21f2, 0x16b3: 0x21f5, 0x16b4: 0x21f8, 0x16b5: 0x21fb, + 0x16b6: 0x21fe, 0x16b7: 0x2201, 0x16b8: 0x2204, 0x16b9: 0x2207, 0x16ba: 0x220a, 0x16bb: 0x220d, + 0x16bc: 0x2210, 0x16bd: 0x2213, 0x16be: 0x2216, 0x16bf: 0x2219, + // Block 0x5b, offset 0x16c0 + 0x16c0: 0x221c, 0x16c1: 0x2221, 0x16c2: 0x2226, 0x16c3: 0x222b, 0x16c4: 0x2230, 0x16c5: 0x2235, + 0x16c6: 0x223a, 0x16c7: 0x223f, 0x16c8: 0x2244, 0x16c9: 0x2249, 0x16ca: 0x224f, 0x16cb: 0x2255, + 0x16cc: 0x225b, 0x16cd: 0x225e, 0x16ce: 0x2262, 0x16cf: 0x2265, 0x16d0: 0x2269, 0x16d1: 0x226d, + 0x16d2: 0x2271, 0x16d3: 0x2275, 0x16d4: 0x2279, 0x16d5: 0x227d, 0x16d6: 0x2281, 0x16d7: 0x2285, + 0x16d8: 0x2289, 0x16d9: 0x228d, 0x16da: 0x2291, 0x16db: 0x2295, 0x16dc: 0x2299, 0x16dd: 0x229d, + 0x16de: 0x22a1, 0x16df: 0x22a5, 0x16e0: 0x22a9, 0x16e1: 0x22ad, 0x16e2: 0x22b1, 0x16e3: 0x22b5, + 0x16e4: 0x22b9, 0x16e5: 0x22bd, 0x16e6: 0x22c1, 0x16e7: 0x22c5, 0x16e8: 0x22c9, 0x16e9: 0x22cd, + 0x16ea: 0x22d1, 0x16eb: 0x22d5, 0x16ec: 0x22d9, 0x16ed: 0x22dd, 0x16ee: 0x22e1, 0x16ef: 0x22e5, + 0x16f0: 0x22e9, 0x16f1: 0x22ed, 0x16f2: 0x22f1, 0x16f3: 0x22f5, 0x16f4: 0x22f9, 0x16f5: 0x22fd, + 0x16f6: 0x2301, 0x16f7: 0x2305, 0x16f8: 0x2309, 0x16f9: 0x230d, 0x16fa: 0x2311, 0x16fb: 0x2315, + 0x16fc: 0x2319, 0x16fd: 0x231d, 0x16fe: 0x2321, + // Block 0x5c, offset 0x1700 + 0x1700: 0x2325, 0x1701: 0x2335, 0x1702: 0x2342, 0x1703: 0x2352, 0x1704: 0x235c, 0x1705: 0x236c, + 0x1706: 0x2376, 0x1707: 0x2380, 0x1708: 0x2393, 0x1709: 0x23a0, 0x170a: 0x23aa, 0x170b: 0x23b4, + 0x170c: 0x23be, 0x170d: 0x23cb, 0x170e: 0x23d8, 0x170f: 0x23e5, 0x1710: 0x23f2, 0x1711: 0x23ff, + 0x1712: 0x240c, 0x1713: 0x2419, 0x1714: 0x242c, 0x1715: 0x2433, 0x1716: 0x2446, 0x1717: 0x2459, + 0x1718: 0x2469, 0x1719: 0x2476, 0x171a: 0x2489, 0x171b: 0x249c, 0x171c: 0x24a9, 0x171d: 0x24b3, + 0x171e: 0x24bd, 0x171f: 0x24ca, 0x1720: 0x24d7, 0x1721: 0x24e7, 0x1722: 0x24f7, 0x1723: 0x2501, + 0x1724: 0x250b, 0x1725: 0x2518, 0x1726: 0x2522, 0x1727: 0x252c, 0x1728: 0x2533, 0x1729: 0x253a, + 0x172a: 0x2544, 0x172b: 0x254e, 0x172c: 0x2561, 0x172d: 0x256e, 0x172e: 0x257e, 0x172f: 0x2591, + 0x1730: 0x259e, 0x1731: 0x25a8, 0x1732: 0x25b2, 0x1733: 0x25c5, 0x1734: 0x25d2, 0x1735: 0x25e5, + 0x1736: 0x25ef, 0x1737: 0x25ff, 0x1738: 0x2609, 0x1739: 0x2616, 0x173a: 0x2620, 0x173b: 0x262d, + 0x173c: 0x263d, 0x173d: 0x264a, 0x173e: 0x265a, 0x173f: 0x2667, + // Block 0x5d, offset 0x1740 + 0x1740: 0x266e, 0x1741: 0x267e, 0x1742: 0x2688, 0x1743: 0x2692, 0x1744: 0x269f, 0x1745: 0x26a9, + 0x1746: 0x26b3, 0x1747: 0x26bd, 0x1748: 0x26cd, 0x1749: 0x26da, 0x174a: 0x26e1, 0x174b: 0x26f4, + 0x174c: 0x26fe, 0x174d: 0x270e, 0x174e: 0x271b, 0x174f: 0x2728, 0x1750: 0x2732, 0x1751: 0x273c, + 0x1752: 0x2749, 0x1753: 0x2750, 0x1754: 0x275d, 0x1755: 0x276d, 0x1756: 0x2774, 0x1757: 0x2787, + 0x1758: 0x2791, 0x1759: 0x2796, 0x175a: 0x279b, 0x175b: 0x27a0, 0x175c: 0x27a5, 0x175d: 0x27aa, + 0x175e: 0x27af, 0x175f: 0x27b4, 0x1760: 0x27b9, 0x1761: 0x27be, 0x1762: 0x27c3, 0x1763: 0x27c9, + 0x1764: 0x27cf, 0x1765: 0x27d5, 0x1766: 0x27db, 0x1767: 0x27e1, 0x1768: 0x27e7, 0x1769: 0x27ed, + 0x176a: 0x27f3, 0x176b: 0x27f9, 0x176c: 0x27ff, 0x176d: 0x2805, 0x176e: 0x280b, 0x176f: 0x2811, + 0x1770: 0x2817, 0x1771: 0x281d, 0x1772: 0x2821, 0x1773: 0x2824, 0x1774: 0x2827, 0x1775: 0x282b, + 0x1776: 0x282e, 0x1777: 0x2831, 0x1778: 0x2834, 0x1779: 0x2838, 0x177a: 0x283c, 0x177b: 0x283f, + 0x177c: 0x2846, 0x177d: 0x284d, 0x177e: 0x2854, 0x177f: 0x285b, + // Block 0x5e, offset 0x1780 + 0x1780: 0x2868, 0x1781: 0x286b, 0x1782: 0x286e, 0x1783: 0x2872, 0x1784: 0x2875, 0x1785: 0x2878, + 0x1786: 0x287b, 0x1787: 0x287e, 0x1788: 0x2881, 0x1789: 0x2885, 0x178a: 0x288a, 0x178b: 0x288d, + 0x178c: 0x2890, 0x178d: 0x2894, 0x178e: 0x2898, 0x178f: 0x289b, 0x1790: 0x289e, 0x1791: 0x28a1, + 0x1792: 0x28a5, 0x1793: 0x28a9, 0x1794: 0x28ad, 0x1795: 0x28b1, 0x1796: 0x28b5, 0x1797: 0x28b8, + 0x1798: 0x28bb, 0x1799: 0x28be, 0x179a: 0x28c1, 0x179b: 0x28c4, 0x179c: 0x28c8, 0x179d: 0x28cb, + 0x179e: 0x28ce, 0x179f: 0x28d1, 0x17a0: 0x28d5, 0x17a1: 0x28d9, 0x17a2: 0x28dc, 0x17a3: 0x28e0, + 0x17a4: 0x28e4, 0x17a5: 0x28e8, 0x17a6: 0x28eb, 0x17a7: 0x28ef, 0x17a8: 0x28f5, 0x17a9: 0x28fc, + 0x17aa: 0x28ff, 0x17ab: 0x2903, 0x17ac: 0x2907, 0x17ad: 0x290b, 0x17ae: 0x290f, 0x17af: 0x2917, + 0x17b0: 0x2920, 0x17b1: 0x2923, 0x17b2: 0x2926, 0x17b3: 0x292a, 0x17b4: 0x292d, 0x17b5: 0x2930, + 0x17b6: 0x2933, 0x17b7: 0x2937, 0x17b8: 0x293a, 0x17b9: 0x293d, 0x17ba: 0x2940, 0x17bb: 0x2943, + 0x17bc: 0x2946, 0x17bd: 0x294a, 0x17be: 0x294d, 0x17bf: 0x2950, + // Block 0x5f, offset 0x17c0 + 0x17c0: 0x2953, 0x17c1: 0x2957, 0x17c2: 0x295b, 0x17c3: 0x2960, 0x17c4: 0x2963, 0x17c5: 0x2966, + 0x17c6: 0x2969, 0x17c7: 0x2970, 0x17c8: 0x2974, 0x17c9: 0x2977, 0x17ca: 0x297a, 0x17cb: 0x297d, + 0x17cc: 0x2980, 0x17cd: 0x2983, 0x17ce: 0x2986, 0x17cf: 0x2989, 0x17d0: 0x298c, 0x17d1: 0x298f, + 0x17d2: 0x2992, 0x17d3: 0x2996, 0x17d4: 0x2999, 0x17d5: 0x299c, 0x17d6: 0x29a0, 0x17d7: 0x29a4, + 0x17d8: 0x29a7, 0x17d9: 0x29ac, 0x17da: 0x29b0, 0x17db: 0x29b3, 0x17dc: 0x29b6, 0x17dd: 0x29b9, + 0x17de: 0x29bc, 0x17df: 0x29c2, 0x17e0: 0x29c8, 0x17e1: 0x29cd, 0x17e2: 0x29d2, 0x17e3: 0x29d7, + 0x17e4: 0x29dc, 0x17e5: 0x29e1, 0x17e6: 0x29e6, 0x17e7: 0x29eb, 0x17e8: 0x29f0, 0x17e9: 0x29f5, + 0x17ea: 0x29fb, 0x17eb: 0x2a01, 0x17ec: 0x2a07, 0x17ed: 0x2a0d, 0x17ee: 0x2a13, 0x17ef: 0x2a19, + 0x17f0: 0x2a1f, 0x17f1: 0x2a25, 0x17f2: 0x2a2b, 0x17f3: 0x2a31, 0x17f4: 0x2a37, 0x17f5: 0x2a3d, + 0x17f6: 0x2a43, 0x17f7: 0x2a49, 0x17f8: 0x2a4f, 0x17f9: 0x2a55, 0x17fa: 0x2a5b, 0x17fb: 0x2a61, + 0x17fc: 0x2a67, 0x17fd: 0x2a6d, 0x17fe: 0x2a73, 0x17ff: 0x2a79, + // Block 0x60, offset 0x1800 + 0x1830: 0x2a7d, + // Block 0x61, offset 0x1840 + 0x1840: 0x2a81, 0x1841: 0x2a85, 0x1842: 0x1a9e, 0x1843: 0x2a89, 0x1844: 0x2a8d, 0x1845: 0x2a91, + 0x1846: 0x2a95, 0x1847: 0x1b76, 0x1848: 0x1b76, 0x1849: 0x2a99, 0x184a: 0x1abe, 0x184b: 0x2a9d, + 0x184c: 0x2aa1, 0x184d: 0x2aa5, 0x184e: 0x2aa9, 0x184f: 0x2aad, 0x1850: 0x2ab1, 0x1851: 0x2ab5, + 0x1852: 0x2ab9, 0x1853: 0x2abd, 0x1854: 0x2ac1, 0x1855: 0x2ac5, 0x1856: 0x2ac9, 0x1857: 0x2acd, + 0x1858: 0x2ad1, 0x1859: 0x2ad5, 0x185a: 0x2ad9, 0x185b: 0x2add, 0x185c: 0x2ae1, 0x185d: 0x2ae5, + 0x185e: 0x2ae9, 0x185f: 0x2aed, 0x1860: 0x2af1, 0x1861: 0x2af5, 0x1862: 0x2af9, 0x1863: 0x2afd, + 0x1864: 0x2b01, 0x1865: 0x2b05, 0x1866: 0x2b09, 0x1867: 0x2b0d, 0x1868: 0x2b11, 0x1869: 0x2b15, + 0x186a: 0x2b19, 0x186b: 0x2b1d, 0x186c: 0x2b21, 0x186d: 0x2b25, 0x186e: 0x2b29, 0x186f: 0x2b2d, + 0x1870: 0x2b31, 0x1871: 0x2b35, 0x1872: 0x2b39, 0x1873: 0x2b3d, 0x1874: 0x1a16, 0x1875: 0x2b41, + 0x1876: 0x2b45, 0x1877: 0x2b49, 0x1878: 0x2b4d, 0x1879: 0x2b51, 0x187a: 0x2b55, 0x187b: 0x2b59, + 0x187c: 0x2b5d, 0x187d: 0x2b61, 0x187e: 0x2b65, 0x187f: 0x2b69, + // Block 0x62, offset 0x1880 + 0x1880: 0x1b3a, 0x1881: 0x2b6d, 0x1882: 0x2b71, 0x1883: 0x2b75, 0x1884: 0x2b79, 0x1885: 0x2b7d, + 0x1886: 0x2b81, 0x1887: 0x2b85, 0x1888: 0x2b89, 0x1889: 0x2b8d, 0x188a: 0x2b91, 0x188b: 0x2b95, + 0x188c: 0x2b99, 0x188d: 0x2b9d, 0x188e: 0x2ba1, 0x188f: 0x2ba5, 0x1890: 0x2ba9, 0x1891: 0x2bad, + 0x1892: 0x2bb1, 0x1893: 0x2bb5, 0x1894: 0x2bb9, 0x1895: 0x2bbd, 0x1896: 0x2bc1, 0x1897: 0x2bc5, + 0x1898: 0x2bc9, 0x1899: 0x2bcd, 0x189a: 0x2bd1, 0x189b: 0x2bd5, 0x189c: 0x2ac1, 0x189d: 0x2bd9, + 0x189e: 0x2bdd, 0x189f: 0x2be1, 0x18a0: 0x2be5, 0x18a1: 0x2be9, 0x18a2: 0x2bed, 0x18a3: 0x2bf1, + 0x18a4: 0x2bf5, 0x18a5: 0x2bf9, 0x18a6: 0x2bfd, 0x18a7: 0x2c01, 0x18a8: 0x2c05, 0x18a9: 0x2c09, + 0x18aa: 0x2c0d, 0x18ab: 0x2c11, 0x18ac: 0x2c15, 0x18ad: 0x2c19, 0x18ae: 0x2c1d, 0x18af: 0x2c21, + 0x18b0: 0x2c25, 0x18b1: 0x1aa6, 0x18b2: 0x2c29, 0x18b3: 0x2c2d, 0x18b4: 0x2c31, 0x18b5: 0x2c35, + 0x18b6: 0x2c39, 0x18b7: 0x2c3d, 0x18b8: 0x2c41, 0x18b9: 0x2c45, 0x18ba: 0x2c49, 0x18bb: 0x2c4d, + 0x18bc: 0x2c51, 0x18bd: 0x2c55, 0x18be: 0x2c59, 0x18bf: 0x2c5d, + // Block 0x63, offset 0x18c0 + 0x18c0: 0x2c61, 0x18c1: 0x18ba, 0x18c2: 0x2c65, 0x18c3: 0x2c69, 0x18c4: 0x2c6d, 0x18c5: 0x2c71, + 0x18c6: 0x2c75, 0x18c7: 0x2c79, 0x18c8: 0x2c7d, 0x18c9: 0x2c81, 0x18ca: 0x186e, 0x18cb: 0x2c85, + 0x18cc: 0x2c89, 0x18cd: 0x2c8d, 0x18ce: 0x2c91, 0x18cf: 0x2c95, 0x18d0: 0x2c99, 0x18d1: 0x2c9d, + 0x18d2: 0x2ca1, 0x18d3: 0x2ca5, 0x18d4: 0x2ca9, 0x18d5: 0x2cad, 0x18d6: 0x2cb1, 0x18d7: 0x2cb5, + 0x18d8: 0x2cb9, 0x18d9: 0x2cbd, 0x18da: 0x2cc1, 0x18db: 0x2cc5, 0x18dc: 0x2cc9, 0x18dd: 0x2ccd, + 0x18de: 0x2cd1, 0x18df: 0x2cd5, 0x18e0: 0x2cd9, 0x18e1: 0x2c21, 0x18e2: 0x2cdd, 0x18e3: 0x2ce1, + 0x18e4: 0x2ce5, 0x18e5: 0x2ce9, 0x18e6: 0x2ced, 0x18e7: 0x2cf1, 0x18e8: 0x2cf5, 0x18e9: 0x2cf9, + 0x18ea: 0x2be1, 0x18eb: 0x2cfd, 0x18ec: 0x2d01, 0x18ed: 0x2d05, 0x18ee: 0x2d09, 0x18ef: 0x2d0d, + 0x18f0: 0x2d11, 0x18f1: 0x2d15, 0x18f2: 0x2d19, 0x18f3: 0x2d1d, 0x18f4: 0x2d21, 0x18f5: 0x2d25, + 0x18f6: 0x2d29, 0x18f7: 0x2d2d, 0x18f8: 0x2d31, 0x18f9: 0x2d35, 0x18fa: 0x2d39, 0x18fb: 0x2d3d, + 0x18fc: 0x2d41, 0x18fd: 0x2d45, 0x18fe: 0x2d49, 0x18ff: 0x2ac1, + // Block 0x64, offset 0x1900 + 0x1900: 0x2d4d, 0x1901: 0x2d51, 0x1902: 0x2d55, 0x1903: 0x2d59, 0x1904: 0x1b72, 0x1905: 0x2d5d, + 0x1906: 0x2d61, 0x1907: 0x2d65, 0x1908: 0x2d69, 0x1909: 0x2d6d, 0x190a: 0x2d71, 0x190b: 0x2d75, + 0x190c: 0x2d79, 0x190d: 0x2d7d, 0x190e: 0x2d81, 0x190f: 0x2d85, 0x1910: 0x2d89, 0x1911: 0x2173, + 0x1912: 0x2d8d, 0x1913: 0x2d91, 0x1914: 0x2d95, 0x1915: 0x2d99, 0x1916: 0x2d9d, 0x1917: 0x2da1, + 0x1918: 0x2da5, 0x1919: 0x2da9, 0x191a: 0x2dad, 0x191b: 0x2be9, 0x191c: 0x2db1, 0x191d: 0x2db5, + 0x191e: 0x2db9, 0x191f: 0x2dbd, 0x1920: 0x2dc1, 0x1921: 0x2dc5, 0x1922: 0x2dc9, 0x1923: 0x2dcd, + 0x1924: 0x2dd1, 0x1925: 0x2dd5, 0x1926: 0x2dd9, 0x1927: 0x2ddd, 0x1928: 0x2de1, 0x1929: 0x1aba, + 0x192a: 0x2de5, 0x192b: 0x2de9, 0x192c: 0x2ded, 0x192d: 0x2df1, 0x192e: 0x2df5, 0x192f: 0x2df9, + 0x1930: 0x2dfd, 0x1931: 0x2e01, 0x1932: 0x2e05, 0x1933: 0x2e09, 0x1934: 0x2e0d, 0x1935: 0x2e11, + 0x1936: 0x2e15, 0x1937: 0x19f6, 0x1938: 0x2e19, 0x1939: 0x2e1d, 0x193a: 0x2e21, 0x193b: 0x2e25, + 0x193c: 0x2e29, 0x193d: 0x2e2d, 0x193e: 0x2e31, 0x193f: 0x2e35, + // Block 0x65, offset 0x1940 + 0x1940: 0x2e39, 0x1941: 0x2e3d, 0x1942: 0x2e41, 0x1943: 0x2e45, 0x1944: 0x2e49, 0x1945: 0x2e4d, + 0x1946: 0x2e51, 0x1947: 0x2e55, 0x1948: 0x1a62, 0x1949: 0x2e59, 0x194a: 0x1a6e, 0x194b: 0x2e5d, + 0x194c: 0x2e61, 0x194d: 0x2e65, 0x1950: 0x2e69, + 0x1952: 0x2e6d, 0x1955: 0x2e71, 0x1956: 0x2e75, 0x1957: 0x2e79, + 0x1958: 0x2e7d, 0x1959: 0x2e81, 0x195a: 0x2e85, 0x195b: 0x2e89, 0x195c: 0x2e8d, 0x195d: 0x2e91, + 0x195e: 0x1a12, 0x1960: 0x2e95, 0x1962: 0x2e99, + 0x1965: 0x2e9d, 0x1966: 0x2ea1, + 0x196a: 0x2ea5, 0x196b: 0x2ea9, 0x196c: 0x2ead, 0x196d: 0x2eb1, + 0x1970: 0x2eb5, 0x1971: 0x2eb9, 0x1972: 0x2ebd, 0x1973: 0x2ec1, 0x1974: 0x2ec5, 0x1975: 0x2ec9, + 0x1976: 0x2ecd, 0x1977: 0x2ed1, 0x1978: 0x2ed5, 0x1979: 0x2ed9, 0x197a: 0x2edd, 0x197b: 0x2ee1, + 0x197c: 0x18d6, 0x197d: 0x2ee5, 0x197e: 0x2ee9, 0x197f: 0x2eed, + // Block 0x66, offset 0x1980 + 0x1980: 0x2ef1, 0x1981: 0x2ef5, 0x1982: 0x2ef9, 0x1983: 0x2efd, 0x1984: 0x2f01, 0x1985: 0x2f05, + 0x1986: 0x2f09, 0x1987: 0x2f0d, 0x1988: 0x2f11, 0x1989: 0x2f15, 0x198a: 0x2f19, 0x198b: 0x2f1d, + 0x198c: 0x2187, 0x198d: 0x2f21, 0x198e: 0x2f25, 0x198f: 0x2f29, 0x1990: 0x2f2d, 0x1991: 0x2197, + 0x1992: 0x2f31, 0x1993: 0x2f35, 0x1994: 0x2f39, 0x1995: 0x2f3d, 0x1996: 0x2f41, 0x1997: 0x2cb1, + 0x1998: 0x2f45, 0x1999: 0x2f49, 0x199a: 0x2f4d, 0x199b: 0x2f51, 0x199c: 0x2f55, 0x199d: 0x2f59, + 0x199e: 0x2f59, 0x199f: 0x2f5d, 0x19a0: 0x2f61, 0x19a1: 0x2f65, 0x19a2: 0x2f69, 0x19a3: 0x2f6d, + 0x19a4: 0x2f71, 0x19a5: 0x2f75, 0x19a6: 0x2f79, 0x19a7: 0x2e9d, 0x19a8: 0x2f7d, 0x19a9: 0x2f81, + 0x19aa: 0x2f85, 0x19ab: 0x2f89, 0x19ac: 0x2f8d, 0x19ad: 0x2f92, + 0x19b0: 0x2f96, 0x19b1: 0x2f9a, 0x19b2: 0x2f9e, 0x19b3: 0x2fa2, 0x19b4: 0x2fa6, 0x19b5: 0x2faa, + 0x19b6: 0x2fae, 0x19b7: 0x2fb2, 0x19b8: 0x2ecd, 0x19b9: 0x2fb6, 0x19ba: 0x2fba, 0x19bb: 0x2fbe, + 0x19bc: 0x2e69, 0x19bd: 0x2fc2, 0x19be: 0x2fc6, 0x19bf: 0x2fca, + // Block 0x67, offset 0x19c0 + 0x19c0: 0x2fce, 0x19c1: 0x2fd2, 0x19c2: 0x2fd6, 0x19c3: 0x2fda, 0x19c4: 0x2fde, 0x19c5: 0x2fe2, + 0x19c6: 0x2fe6, 0x19c7: 0x2fea, 0x19c8: 0x2fee, 0x19c9: 0x2eed, 0x19ca: 0x2ff2, 0x19cb: 0x2ef1, + 0x19cc: 0x2ff6, 0x19cd: 0x2ffa, 0x19ce: 0x2ffe, 0x19cf: 0x3002, 0x19d0: 0x3006, 0x19d1: 0x2e6d, + 0x19d2: 0x2b15, 0x19d3: 0x300a, 0x19d4: 0x300e, 0x19d5: 0x195a, 0x19d6: 0x2c25, 0x19d7: 0x2d71, + 0x19d8: 0x3012, 0x19d9: 0x3016, 0x19da: 0x2f0d, 0x19db: 0x301a, 0x19dc: 0x2f11, 0x19dd: 0x301e, + 0x19de: 0x3022, 0x19df: 0x3026, 0x19e0: 0x2e75, 0x19e1: 0x302a, 0x19e2: 0x302e, 0x19e3: 0x3032, + 0x19e4: 0x3036, 0x19e5: 0x303a, 0x19e6: 0x2e79, 0x19e7: 0x303e, 0x19e8: 0x3042, 0x19e9: 0x3046, + 0x19ea: 0x304a, 0x19eb: 0x304e, 0x19ec: 0x3052, 0x19ed: 0x2f41, 0x19ee: 0x3056, 0x19ef: 0x305a, + 0x19f0: 0x2cb1, 0x19f1: 0x305e, 0x19f2: 0x2f51, 0x19f3: 0x3062, 0x19f4: 0x3066, 0x19f5: 0x306a, + 0x19f6: 0x306e, 0x19f7: 0x3072, 0x19f8: 0x2f65, 0x19f9: 0x3076, 0x19fa: 0x2e99, 0x19fb: 0x307a, + 0x19fc: 0x2f69, 0x19fd: 0x2bd9, 0x19fe: 0x307e, 0x19ff: 0x2f6d, + // Block 0x68, offset 0x1a00 + 0x1a00: 0x3082, 0x1a01: 0x2f75, 0x1a02: 0x3086, 0x1a03: 0x308a, 0x1a04: 0x308e, 0x1a05: 0x3092, + 0x1a06: 0x3096, 0x1a07: 0x2f7d, 0x1a08: 0x2e8d, 0x1a09: 0x309a, 0x1a0a: 0x2f81, 0x1a0b: 0x309e, + 0x1a0c: 0x2f85, 0x1a0d: 0x30a2, 0x1a0e: 0x1b76, 0x1a0f: 0x30a6, 0x1a10: 0x30ab, 0x1a11: 0x30b0, + 0x1a12: 0x30b5, 0x1a13: 0x30b9, 0x1a14: 0x30bd, 0x1a15: 0x30c1, 0x1a16: 0x30c6, 0x1a17: 0x30cb, + 0x1a18: 0x30d0, 0x1a19: 0x30d4, + // Block 0x69, offset 0x1a40 + 0x1a40: 0x30d8, 0x1a41: 0x30db, 0x1a42: 0x30de, 0x1a43: 0x30e1, 0x1a44: 0x30e5, 0x1a45: 0x30e9, + 0x1a46: 0x30e9, + 0x1a53: 0x30ec, 0x1a54: 0x30f1, 0x1a55: 0x30f6, 0x1a56: 0x30fb, 0x1a57: 0x3100, + 0x1a5d: 0x3105, + 0x1a5f: 0x310a, 0x1a60: 0x310f, 0x1a61: 0x14db, 0x1a62: 0x14e4, 0x1a63: 0x3112, + 0x1a64: 0x3115, 0x1a65: 0x3118, 0x1a66: 0x311b, 0x1a67: 0x311e, 0x1a68: 0x3121, 0x1a69: 0x1494, + 0x1a6a: 0x3124, 0x1a6b: 0x3129, 0x1a6c: 0x312e, 0x1a6d: 0x3135, 0x1a6e: 0x313c, 0x1a6f: 0x3141, + 0x1a70: 0x3146, 0x1a71: 0x314b, 0x1a72: 0x3150, 0x1a73: 0x3155, 0x1a74: 0x315a, 0x1a75: 0x315f, + 0x1a76: 0x3164, 0x1a78: 0x3169, 0x1a79: 0x316e, 0x1a7a: 0x3173, 0x1a7b: 0x3178, + 0x1a7c: 0x317d, 0x1a7e: 0x3182, + // Block 0x6a, offset 0x1a80 + 0x1a80: 0x3187, 0x1a81: 0x318c, 0x1a83: 0x3191, 0x1a84: 0x3196, + 0x1a86: 0x319b, 0x1a87: 0x31a0, 0x1a88: 0x31a5, 0x1a89: 0x31aa, 0x1a8a: 0x31af, 0x1a8b: 0x31b4, + 0x1a8c: 0x31b9, 0x1a8d: 0x31be, 0x1a8e: 0x31c3, 0x1a8f: 0x31c8, 0x1a90: 0x31cd, 0x1a91: 0x31cd, + 0x1a92: 0x31d0, 0x1a93: 0x31d0, 0x1a94: 0x31d0, 0x1a95: 0x31d0, 0x1a96: 0x31d3, 0x1a97: 0x31d3, + 0x1a98: 0x31d3, 0x1a99: 0x31d3, 0x1a9a: 0x31d6, 0x1a9b: 0x31d6, 0x1a9c: 0x31d6, 0x1a9d: 0x31d6, + 0x1a9e: 0x31d9, 0x1a9f: 0x31d9, 0x1aa0: 0x31d9, 0x1aa1: 0x31d9, 0x1aa2: 0x31dc, 0x1aa3: 0x31dc, + 0x1aa4: 0x31dc, 0x1aa5: 0x31dc, 0x1aa6: 0x31df, 0x1aa7: 0x31df, 0x1aa8: 0x31df, 0x1aa9: 0x31df, + 0x1aaa: 0x31e2, 0x1aab: 0x31e2, 0x1aac: 0x31e2, 0x1aad: 0x31e2, 0x1aae: 0x31e5, 0x1aaf: 0x31e5, + 0x1ab0: 0x31e5, 0x1ab1: 0x31e5, 0x1ab2: 0x31e8, 0x1ab3: 0x31e8, 0x1ab4: 0x31e8, 0x1ab5: 0x31e8, + 0x1ab6: 0x31eb, 0x1ab7: 0x31eb, 0x1ab8: 0x31eb, 0x1ab9: 0x31eb, 0x1aba: 0x31ee, 0x1abb: 0x31ee, + 0x1abc: 0x31ee, 0x1abd: 0x31ee, 0x1abe: 0x31f1, 0x1abf: 0x31f1, + // Block 0x6b, offset 0x1ac0 + 0x1ac0: 0x31f1, 0x1ac1: 0x31f1, 0x1ac2: 0x31f4, 0x1ac3: 0x31f4, 0x1ac4: 0x31f7, 0x1ac5: 0x31f7, + 0x1ac6: 0x31fa, 0x1ac7: 0x31fa, 0x1ac8: 0x31fd, 0x1ac9: 0x31fd, 0x1aca: 0x3200, 0x1acb: 0x3200, + 0x1acc: 0x3203, 0x1acd: 0x3203, 0x1ace: 0x3206, 0x1acf: 0x3206, 0x1ad0: 0x3206, 0x1ad1: 0x3206, + 0x1ad2: 0x3209, 0x1ad3: 0x3209, 0x1ad4: 0x3209, 0x1ad5: 0x3209, 0x1ad6: 0x320c, 0x1ad7: 0x320c, + 0x1ad8: 0x320c, 0x1ad9: 0x320c, 0x1ada: 0x320f, 0x1adb: 0x320f, 0x1adc: 0x320f, 0x1add: 0x320f, + 0x1ade: 0x3212, 0x1adf: 0x3212, 0x1ae0: 0x3215, 0x1ae1: 0x3215, 0x1ae2: 0x3215, 0x1ae3: 0x3215, + 0x1ae4: 0x06ba, 0x1ae5: 0x06ba, 0x1ae6: 0x3218, 0x1ae7: 0x3218, 0x1ae8: 0x3218, 0x1ae9: 0x3218, + 0x1aea: 0x321b, 0x1aeb: 0x321b, 0x1aec: 0x321b, 0x1aed: 0x321b, 0x1aee: 0x321e, 0x1aef: 0x321e, + 0x1af0: 0x06c4, 0x1af1: 0x06c4, + // Block 0x6c, offset 0x1b00 + 0x1b13: 0x3221, 0x1b14: 0x3221, 0x1b15: 0x3221, 0x1b16: 0x3221, 0x1b17: 0x3224, + 0x1b18: 0x3224, 0x1b19: 0x3227, 0x1b1a: 0x3227, 0x1b1b: 0x322a, 0x1b1c: 0x322a, 0x1b1d: 0x06b0, + 0x1b1e: 0x322d, 0x1b1f: 0x322d, 0x1b20: 0x3230, 0x1b21: 0x3230, 0x1b22: 0x3233, 0x1b23: 0x3233, + 0x1b24: 0x3236, 0x1b25: 0x3236, 0x1b26: 0x3236, 0x1b27: 0x3236, 0x1b28: 0x3239, 0x1b29: 0x3239, + 0x1b2a: 0x323c, 0x1b2b: 0x323c, 0x1b2c: 0x3243, 0x1b2d: 0x3243, 0x1b2e: 0x324a, 0x1b2f: 0x324a, + 0x1b30: 0x3251, 0x1b31: 0x3251, 0x1b32: 0x3258, 0x1b33: 0x3258, 0x1b34: 0x325f, 0x1b35: 0x325f, + 0x1b36: 0x3266, 0x1b37: 0x3266, 0x1b38: 0x3266, 0x1b39: 0x326d, 0x1b3a: 0x326d, 0x1b3b: 0x326d, + 0x1b3c: 0x3274, 0x1b3d: 0x3274, 0x1b3e: 0x3274, 0x1b3f: 0x3274, + // Block 0x6d, offset 0x1b40 + 0x1b40: 0x3277, 0x1b41: 0x327e, 0x1b42: 0x3285, 0x1b43: 0x326d, 0x1b44: 0x328c, 0x1b45: 0x3293, + 0x1b46: 0x3298, 0x1b47: 0x329d, 0x1b48: 0x32a2, 0x1b49: 0x32a7, 0x1b4a: 0x32ac, 0x1b4b: 0x32b1, + 0x1b4c: 0x32b6, 0x1b4d: 0x32bb, 0x1b4e: 0x32c0, 0x1b4f: 0x32c5, 0x1b50: 0x32ca, 0x1b51: 0x32cf, + 0x1b52: 0x32d4, 0x1b53: 0x32d9, 0x1b54: 0x32de, 0x1b55: 0x32e3, 0x1b56: 0x32e8, 0x1b57: 0x32ed, + 0x1b58: 0x32f2, 0x1b59: 0x32f7, 0x1b5a: 0x32fc, 0x1b5b: 0x3301, 0x1b5c: 0x3306, 0x1b5d: 0x330b, + 0x1b5e: 0x3310, 0x1b5f: 0x3315, 0x1b60: 0x331a, 0x1b61: 0x331f, 0x1b62: 0x3324, 0x1b63: 0x3329, + 0x1b64: 0x332e, 0x1b65: 0x3333, 0x1b66: 0x3338, 0x1b67: 0x333d, 0x1b68: 0x3342, 0x1b69: 0x3347, + 0x1b6a: 0x334c, 0x1b6b: 0x3351, 0x1b6c: 0x3356, 0x1b6d: 0x335b, 0x1b6e: 0x3360, 0x1b6f: 0x3365, + 0x1b70: 0x336a, 0x1b71: 0x336f, 0x1b72: 0x3374, 0x1b73: 0x3379, 0x1b74: 0x337e, 0x1b75: 0x3383, + 0x1b76: 0x3388, 0x1b77: 0x338d, 0x1b78: 0x3392, 0x1b79: 0x3397, 0x1b7a: 0x339c, 0x1b7b: 0x33a1, + 0x1b7c: 0x33a6, 0x1b7d: 0x33ab, 0x1b7e: 0x33b0, 0x1b7f: 0x33b5, + // Block 0x6e, offset 0x1b80 + 0x1b80: 0x33ba, 0x1b81: 0x33bf, 0x1b82: 0x33c4, 0x1b83: 0x33c9, 0x1b84: 0x33ce, 0x1b85: 0x33d3, + 0x1b86: 0x33d8, 0x1b87: 0x33dd, 0x1b88: 0x33e2, 0x1b89: 0x33e7, 0x1b8a: 0x33ec, 0x1b8b: 0x33f1, + 0x1b8c: 0x33f6, 0x1b8d: 0x33fb, 0x1b8e: 0x3400, 0x1b8f: 0x3405, 0x1b90: 0x340a, 0x1b91: 0x340f, + 0x1b92: 0x3414, 0x1b93: 0x3419, 0x1b94: 0x341e, 0x1b95: 0x3423, 0x1b96: 0x3428, 0x1b97: 0x342d, + 0x1b98: 0x3432, 0x1b99: 0x3437, 0x1b9a: 0x343c, 0x1b9b: 0x3441, 0x1b9c: 0x3446, 0x1b9d: 0x344b, + 0x1b9e: 0x3450, 0x1b9f: 0x3456, 0x1ba0: 0x345c, 0x1ba1: 0x3462, 0x1ba2: 0x3468, 0x1ba3: 0x346e, + 0x1ba4: 0x3474, 0x1ba5: 0x347b, 0x1ba6: 0x3285, 0x1ba7: 0x3482, 0x1ba8: 0x326d, 0x1ba9: 0x328c, + 0x1baa: 0x3489, 0x1bab: 0x348e, 0x1bac: 0x32a2, 0x1bad: 0x3493, 0x1bae: 0x32a7, 0x1baf: 0x32ac, + 0x1bb0: 0x3498, 0x1bb1: 0x349d, 0x1bb2: 0x32c0, 0x1bb3: 0x34a2, 0x1bb4: 0x32c5, 0x1bb5: 0x32ca, + 0x1bb6: 0x34a7, 0x1bb7: 0x34ac, 0x1bb8: 0x32d4, 0x1bb9: 0x34b1, 0x1bba: 0x32d9, 0x1bbb: 0x32de, + 0x1bbc: 0x336f, 0x1bbd: 0x3374, 0x1bbe: 0x3383, 0x1bbf: 0x3388, + // Block 0x6f, offset 0x1bc0 + 0x1bc0: 0x338d, 0x1bc1: 0x33a1, 0x1bc2: 0x33a6, 0x1bc3: 0x33ab, 0x1bc4: 0x33b0, 0x1bc5: 0x33c4, + 0x1bc6: 0x33c9, 0x1bc7: 0x33ce, 0x1bc8: 0x34b6, 0x1bc9: 0x33e2, 0x1bca: 0x34bb, 0x1bcb: 0x34c0, + 0x1bcc: 0x3400, 0x1bcd: 0x34c5, 0x1bce: 0x3405, 0x1bcf: 0x340a, 0x1bd0: 0x344b, 0x1bd1: 0x34ca, + 0x1bd2: 0x34cf, 0x1bd3: 0x3432, 0x1bd4: 0x34d4, 0x1bd5: 0x3437, 0x1bd6: 0x343c, 0x1bd7: 0x3277, + 0x1bd8: 0x327e, 0x1bd9: 0x34d9, 0x1bda: 0x3285, 0x1bdb: 0x34e0, 0x1bdc: 0x3293, 0x1bdd: 0x3298, + 0x1bde: 0x329d, 0x1bdf: 0x32a2, 0x1be0: 0x34e7, 0x1be1: 0x32b1, 0x1be2: 0x32b6, 0x1be3: 0x32bb, + 0x1be4: 0x32c0, 0x1be5: 0x34ec, 0x1be6: 0x32d4, 0x1be7: 0x32e3, 0x1be8: 0x32e8, 0x1be9: 0x32ed, + 0x1bea: 0x32f2, 0x1beb: 0x32f7, 0x1bec: 0x3301, 0x1bed: 0x3306, 0x1bee: 0x330b, 0x1bef: 0x3310, + 0x1bf0: 0x3315, 0x1bf1: 0x331a, 0x1bf2: 0x34f1, 0x1bf3: 0x331f, 0x1bf4: 0x3324, 0x1bf5: 0x3329, + 0x1bf6: 0x332e, 0x1bf7: 0x3333, 0x1bf8: 0x3338, 0x1bf9: 0x3342, 0x1bfa: 0x3347, 0x1bfb: 0x334c, + 0x1bfc: 0x3351, 0x1bfd: 0x3356, 0x1bfe: 0x335b, 0x1bff: 0x3360, + // Block 0x70, offset 0x1c00 + 0x1c00: 0x3365, 0x1c01: 0x336a, 0x1c02: 0x3379, 0x1c03: 0x337e, 0x1c04: 0x3392, 0x1c05: 0x3397, + 0x1c06: 0x339c, 0x1c07: 0x33a1, 0x1c08: 0x33a6, 0x1c09: 0x33b5, 0x1c0a: 0x33ba, 0x1c0b: 0x33bf, + 0x1c0c: 0x33c4, 0x1c0d: 0x34f6, 0x1c0e: 0x33d3, 0x1c0f: 0x33d8, 0x1c10: 0x33dd, 0x1c11: 0x33e2, + 0x1c12: 0x33f1, 0x1c13: 0x33f6, 0x1c14: 0x33fb, 0x1c15: 0x3400, 0x1c16: 0x34fb, 0x1c17: 0x340f, + 0x1c18: 0x3414, 0x1c19: 0x3500, 0x1c1a: 0x3423, 0x1c1b: 0x3428, 0x1c1c: 0x342d, 0x1c1d: 0x3432, + 0x1c1e: 0x3505, 0x1c1f: 0x3285, 0x1c20: 0x34e0, 0x1c21: 0x32a2, 0x1c22: 0x34e7, 0x1c23: 0x32c0, + 0x1c24: 0x34ec, 0x1c25: 0x32d4, 0x1c26: 0x350a, 0x1c27: 0x3315, 0x1c28: 0x350f, 0x1c29: 0x3514, + 0x1c2a: 0x3519, 0x1c2b: 0x33a1, 0x1c2c: 0x33a6, 0x1c2d: 0x33c4, 0x1c2e: 0x3400, 0x1c2f: 0x34fb, + 0x1c30: 0x3432, 0x1c31: 0x3505, 0x1c32: 0x351e, 0x1c33: 0x3525, 0x1c34: 0x352c, 0x1c35: 0x3533, + 0x1c36: 0x3538, 0x1c37: 0x353d, 0x1c38: 0x3542, 0x1c39: 0x3547, 0x1c3a: 0x354c, 0x1c3b: 0x3551, + 0x1c3c: 0x3556, 0x1c3d: 0x355b, 0x1c3e: 0x3560, 0x1c3f: 0x3565, + // Block 0x71, offset 0x1c40 + 0x1c40: 0x356a, 0x1c41: 0x356f, 0x1c42: 0x3574, 0x1c43: 0x3579, 0x1c44: 0x357e, 0x1c45: 0x3583, + 0x1c46: 0x3588, 0x1c47: 0x358d, 0x1c48: 0x3592, 0x1c49: 0x3597, 0x1c4a: 0x359c, 0x1c4b: 0x35a1, + 0x1c4c: 0x3514, 0x1c4d: 0x35a6, 0x1c4e: 0x35ab, 0x1c4f: 0x35b0, 0x1c50: 0x35b5, 0x1c51: 0x3533, + 0x1c52: 0x3538, 0x1c53: 0x353d, 0x1c54: 0x3542, 0x1c55: 0x3547, 0x1c56: 0x354c, 0x1c57: 0x3551, + 0x1c58: 0x3556, 0x1c59: 0x355b, 0x1c5a: 0x3560, 0x1c5b: 0x3565, 0x1c5c: 0x356a, 0x1c5d: 0x356f, + 0x1c5e: 0x3574, 0x1c5f: 0x3579, 0x1c60: 0x357e, 0x1c61: 0x3583, 0x1c62: 0x3588, 0x1c63: 0x358d, + 0x1c64: 0x3592, 0x1c65: 0x3597, 0x1c66: 0x359c, 0x1c67: 0x35a1, 0x1c68: 0x3514, 0x1c69: 0x35a6, + 0x1c6a: 0x35ab, 0x1c6b: 0x35b0, 0x1c6c: 0x35b5, 0x1c6d: 0x3597, 0x1c6e: 0x359c, 0x1c6f: 0x35a1, + 0x1c70: 0x3514, 0x1c71: 0x350f, 0x1c72: 0x3519, 0x1c73: 0x333d, 0x1c74: 0x3306, 0x1c75: 0x330b, + 0x1c76: 0x3310, 0x1c77: 0x3597, 0x1c78: 0x359c, 0x1c79: 0x35a1, 0x1c7a: 0x333d, 0x1c7b: 0x3342, + 0x1c7c: 0x35ba, 0x1c7d: 0x35ba, + // Block 0x72, offset 0x1c80 + 0x1c90: 0x35bf, 0x1c91: 0x35c6, + 0x1c92: 0x35c6, 0x1c93: 0x35cd, 0x1c94: 0x35d4, 0x1c95: 0x35db, 0x1c96: 0x35e2, 0x1c97: 0x35e9, + 0x1c98: 0x35f0, 0x1c99: 0x35f0, 0x1c9a: 0x35f7, 0x1c9b: 0x35fe, 0x1c9c: 0x3605, 0x1c9d: 0x360c, + 0x1c9e: 0x3613, 0x1c9f: 0x361a, 0x1ca0: 0x361a, 0x1ca1: 0x3621, 0x1ca2: 0x3628, 0x1ca3: 0x3628, + 0x1ca4: 0x362f, 0x1ca5: 0x362f, 0x1ca6: 0x3636, 0x1ca7: 0x363d, 0x1ca8: 0x363d, 0x1ca9: 0x3644, + 0x1caa: 0x364b, 0x1cab: 0x364b, 0x1cac: 0x3652, 0x1cad: 0x3652, 0x1cae: 0x3659, 0x1caf: 0x3660, + 0x1cb0: 0x3660, 0x1cb1: 0x3667, 0x1cb2: 0x3667, 0x1cb3: 0x366e, 0x1cb4: 0x3675, 0x1cb5: 0x367c, + 0x1cb6: 0x3683, 0x1cb7: 0x3683, 0x1cb8: 0x368a, 0x1cb9: 0x3691, 0x1cba: 0x3698, 0x1cbb: 0x369f, + 0x1cbc: 0x36a6, 0x1cbd: 0x36a6, 0x1cbe: 0x36ad, 0x1cbf: 0x36b4, + // Block 0x73, offset 0x1cc0 + 0x1cc0: 0x36bb, 0x1cc1: 0x36c2, 0x1cc2: 0x36c9, 0x1cc3: 0x36d0, 0x1cc4: 0x36d0, 0x1cc5: 0x36d7, + 0x1cc6: 0x36d7, 0x1cc7: 0x36de, 0x1cc8: 0x36de, 0x1cc9: 0x36e5, 0x1cca: 0x36ec, 0x1ccb: 0x36f3, + 0x1ccc: 0x36fa, 0x1ccd: 0x3701, 0x1cce: 0x3708, 0x1ccf: 0x370f, + 0x1cd2: 0x3716, 0x1cd3: 0x371d, 0x1cd4: 0x3724, 0x1cd5: 0x372b, 0x1cd6: 0x3732, 0x1cd7: 0x3739, + 0x1cd8: 0x3739, 0x1cd9: 0x3740, 0x1cda: 0x3747, 0x1cdb: 0x374e, 0x1cdc: 0x3755, 0x1cdd: 0x3755, + 0x1cde: 0x375c, 0x1cdf: 0x3763, 0x1ce0: 0x376a, 0x1ce1: 0x3771, 0x1ce2: 0x3778, 0x1ce3: 0x377f, + 0x1ce4: 0x3786, 0x1ce5: 0x378d, 0x1ce6: 0x3794, 0x1ce7: 0x379b, 0x1ce8: 0x37a2, 0x1ce9: 0x37a9, + 0x1cea: 0x37b0, 0x1ceb: 0x37b7, 0x1cec: 0x37be, 0x1ced: 0x37c5, 0x1cee: 0x37cc, 0x1cef: 0x37d3, + 0x1cf0: 0x37da, 0x1cf1: 0x37e1, 0x1cf2: 0x37e8, 0x1cf3: 0x37ef, 0x1cf4: 0x36ad, 0x1cf5: 0x36bb, + 0x1cf6: 0x37f6, 0x1cf7: 0x37fd, 0x1cf8: 0x3804, 0x1cf9: 0x380b, 0x1cfa: 0x3812, 0x1cfb: 0x3819, + 0x1cfc: 0x3812, 0x1cfd: 0x3804, 0x1cfe: 0x3820, 0x1cff: 0x3827, + // Block 0x74, offset 0x1d00 + 0x1d00: 0x382e, 0x1d01: 0x3835, 0x1d02: 0x383c, 0x1d03: 0x3819, 0x1d04: 0x367c, 0x1d05: 0x3636, + 0x1d06: 0x3843, 0x1d07: 0x384a, + 0x1d30: 0x3851, 0x1d31: 0x3858, 0x1d32: 0x385f, 0x1d33: 0x3868, 0x1d34: 0x3871, 0x1d35: 0x387a, + 0x1d36: 0x3883, 0x1d37: 0x388c, 0x1d38: 0x3895, 0x1d39: 0x389e, 0x1d3a: 0x38a5, 0x1d3b: 0x38c7, + 0x1d3c: 0x38d7, + // Block 0x75, offset 0x1d40 + 0x1d50: 0x38e0, 0x1d51: 0x38e2, + 0x1d52: 0x38e6, 0x1d53: 0x38ea, 0x1d54: 0x04e1, 0x1d55: 0x38ec, 0x1d56: 0x38ee, 0x1d57: 0x38f0, + 0x1d58: 0x38f4, 0x1d59: 0x1443, + 0x1d70: 0x1440, 0x1d71: 0x38f8, 0x1d72: 0x38fc, 0x1d73: 0x3900, 0x1d74: 0x3900, 0x1d75: 0x149c, + 0x1d76: 0x149e, 0x1d77: 0x3902, 0x1d78: 0x3904, 0x1d79: 0x3906, 0x1d7a: 0x390a, 0x1d7b: 0x390e, + 0x1d7c: 0x3912, 0x1d7d: 0x3916, 0x1d7e: 0x391a, 0x1d7f: 0x16c3, + // Block 0x76, offset 0x1d80 + 0x1d80: 0x16c7, 0x1d81: 0x391e, 0x1d82: 0x3922, 0x1d83: 0x3926, 0x1d84: 0x392a, + 0x1d87: 0x392e, 0x1d88: 0x3930, 0x1d89: 0x146c, 0x1d8a: 0x146c, 0x1d8b: 0x146c, + 0x1d8c: 0x146c, 0x1d8d: 0x3900, 0x1d8e: 0x3900, 0x1d8f: 0x3900, 0x1d90: 0x38e0, 0x1d91: 0x38e2, + 0x1d92: 0x143e, 0x1d94: 0x04e1, 0x1d95: 0x38ea, 0x1d96: 0x38ee, 0x1d97: 0x38ec, + 0x1d98: 0x38f8, 0x1d99: 0x149c, 0x1d9a: 0x149e, 0x1d9b: 0x3902, 0x1d9c: 0x3904, 0x1d9d: 0x3906, + 0x1d9e: 0x390a, 0x1d9f: 0x3932, 0x1da0: 0x3934, 0x1da1: 0x3936, 0x1da2: 0x1494, 0x1da3: 0x3938, + 0x1da4: 0x393a, 0x1da5: 0x393c, 0x1da6: 0x149a, 0x1da8: 0x393e, 0x1da9: 0x3940, + 0x1daa: 0x3942, 0x1dab: 0x3944, + 0x1db0: 0x3946, 0x1db1: 0x394a, 0x1db2: 0x394f, 0x1db4: 0x3953, + 0x1db6: 0x3957, 0x1db7: 0x395b, 0x1db8: 0x3960, 0x1db9: 0x3964, 0x1dba: 0x3969, 0x1dbb: 0x396d, + 0x1dbc: 0x3972, 0x1dbd: 0x3976, 0x1dbe: 0x397b, 0x1dbf: 0x397f, + // Block 0x77, offset 0x1dc0 + 0x1dc0: 0x3984, 0x1dc1: 0x068d, 0x1dc2: 0x068d, 0x1dc3: 0x0692, 0x1dc4: 0x0692, 0x1dc5: 0x0697, + 0x1dc6: 0x0697, 0x1dc7: 0x069c, 0x1dc8: 0x069c, 0x1dc9: 0x06a1, 0x1dca: 0x06a1, 0x1dcb: 0x06a1, + 0x1dcc: 0x06a1, 0x1dcd: 0x3987, 0x1dce: 0x3987, 0x1dcf: 0x398a, 0x1dd0: 0x398a, 0x1dd1: 0x398a, + 0x1dd2: 0x398a, 0x1dd3: 0x398d, 0x1dd4: 0x398d, 0x1dd5: 0x3990, 0x1dd6: 0x3990, 0x1dd7: 0x3990, + 0x1dd8: 0x3990, 0x1dd9: 0x3993, 0x1dda: 0x3993, 0x1ddb: 0x3993, 0x1ddc: 0x3993, 0x1ddd: 0x3996, + 0x1dde: 0x3996, 0x1ddf: 0x3996, 0x1de0: 0x3996, 0x1de1: 0x3999, 0x1de2: 0x3999, 0x1de3: 0x3999, + 0x1de4: 0x3999, 0x1de5: 0x399c, 0x1de6: 0x399c, 0x1de7: 0x399c, 0x1de8: 0x399c, 0x1de9: 0x399f, + 0x1dea: 0x399f, 0x1deb: 0x39a2, 0x1dec: 0x39a2, 0x1ded: 0x39a5, 0x1dee: 0x39a5, 0x1def: 0x39a8, + 0x1df0: 0x39a8, 0x1df1: 0x39ab, 0x1df2: 0x39ab, 0x1df3: 0x39ab, 0x1df4: 0x39ab, 0x1df5: 0x39ae, + 0x1df6: 0x39ae, 0x1df7: 0x39ae, 0x1df8: 0x39ae, 0x1df9: 0x39b1, 0x1dfa: 0x39b1, 0x1dfb: 0x39b1, + 0x1dfc: 0x39b1, 0x1dfd: 0x39b4, 0x1dfe: 0x39b4, 0x1dff: 0x39b4, + // Block 0x78, offset 0x1e00 + 0x1e00: 0x39b4, 0x1e01: 0x39b7, 0x1e02: 0x39b7, 0x1e03: 0x39b7, 0x1e04: 0x39b7, 0x1e05: 0x39ba, + 0x1e06: 0x39ba, 0x1e07: 0x39ba, 0x1e08: 0x39ba, 0x1e09: 0x39bd, 0x1e0a: 0x39bd, 0x1e0b: 0x39bd, + 0x1e0c: 0x39bd, 0x1e0d: 0x39c0, 0x1e0e: 0x39c0, 0x1e0f: 0x39c0, 0x1e10: 0x39c0, 0x1e11: 0x39c3, + 0x1e12: 0x39c3, 0x1e13: 0x39c3, 0x1e14: 0x39c3, 0x1e15: 0x39c6, 0x1e16: 0x39c6, 0x1e17: 0x39c6, + 0x1e18: 0x39c6, 0x1e19: 0x39c9, 0x1e1a: 0x39c9, 0x1e1b: 0x39c9, 0x1e1c: 0x39c9, 0x1e1d: 0x39cc, + 0x1e1e: 0x39cc, 0x1e1f: 0x39cc, 0x1e20: 0x39cc, 0x1e21: 0x39cf, 0x1e22: 0x39cf, 0x1e23: 0x39cf, + 0x1e24: 0x39cf, 0x1e25: 0x39d2, 0x1e26: 0x39d2, 0x1e27: 0x39d2, 0x1e28: 0x39d2, 0x1e29: 0x39d5, + 0x1e2a: 0x39d5, 0x1e2b: 0x39d5, 0x1e2c: 0x39d5, 0x1e2d: 0x39d8, 0x1e2e: 0x39d8, 0x1e2f: 0x3239, + 0x1e30: 0x3239, 0x1e31: 0x39db, 0x1e32: 0x39db, 0x1e33: 0x39db, 0x1e34: 0x39db, 0x1e35: 0x39de, + 0x1e36: 0x39de, 0x1e37: 0x39e5, 0x1e38: 0x39e5, 0x1e39: 0x39ec, 0x1e3a: 0x39ec, 0x1e3b: 0x39f3, + 0x1e3c: 0x39f3, + // Block 0x79, offset 0x1e40 + 0x1e41: 0x38ec, 0x1e42: 0x39f8, 0x1e43: 0x3932, 0x1e44: 0x3940, 0x1e45: 0x3942, + 0x1e46: 0x3934, 0x1e47: 0x39fa, 0x1e48: 0x149c, 0x1e49: 0x149e, 0x1e4a: 0x3936, 0x1e4b: 0x1494, + 0x1e4c: 0x38e0, 0x1e4d: 0x3938, 0x1e4e: 0x143e, 0x1e4f: 0x39fc, 0x1e50: 0x1486, 0x1e51: 0x001c, + 0x1e52: 0x000d, 0x1e53: 0x000f, 0x1e54: 0x1488, 0x1e55: 0x148a, 0x1e56: 0x148c, 0x1e57: 0x148e, + 0x1e58: 0x1490, 0x1e59: 0x1492, 0x1e5a: 0x38ea, 0x1e5b: 0x04e1, 0x1e5c: 0x393a, 0x1e5d: 0x149a, + 0x1e5e: 0x393c, 0x1e5f: 0x38ee, 0x1e60: 0x3944, 0x1e61: 0x0906, 0x1e62: 0x090b, 0x1e63: 0x14ad, + 0x1e64: 0x090d, 0x1e65: 0x090f, 0x1e66: 0x14d9, 0x1e67: 0x0914, 0x1e68: 0x0916, 0x1e69: 0x0918, + 0x1e6a: 0x091a, 0x1e6b: 0x091c, 0x1e6c: 0x091e, 0x1e6d: 0x0920, 0x1e6e: 0x0922, 0x1e6f: 0x0924, + 0x1e70: 0x0929, 0x1e71: 0x14c8, 0x1e72: 0x092b, 0x1e73: 0x17f6, 0x1e74: 0x092d, 0x1e75: 0x092f, + 0x1e76: 0x155f, 0x1e77: 0x0931, 0x1e78: 0x1570, 0x1e79: 0x17f8, 0x1e7a: 0x14d4, 0x1e7b: 0x392e, + 0x1e7c: 0x393e, 0x1e7d: 0x3930, 0x1e7e: 0x39fe, 0x1e7f: 0x3900, + // Block 0x7a, offset 0x1e80 + 0x1e80: 0x13f7, 0x1e81: 0x0007, 0x1e82: 0x093d, 0x1e83: 0x0984, 0x1e84: 0x093f, 0x1e85: 0x0941, + 0x1e86: 0x098c, 0x1e87: 0x094c, 0x1e88: 0x0494, 0x1e89: 0x097c, 0x1e8a: 0x0499, 0x1e8b: 0x094e, + 0x1e8c: 0x04c5, 0x1e8d: 0x0950, 0x1e8e: 0x14a0, 0x1e8f: 0x001e, 0x1e90: 0x0960, 0x1e91: 0x17fa, + 0x1e92: 0x049b, 0x1e93: 0x02c8, 0x1e94: 0x0962, 0x1e95: 0x0964, 0x1e96: 0x096d, 0x1e97: 0x04a6, + 0x1e98: 0x04c7, 0x1e99: 0x04a8, 0x1e9a: 0x09df, 0x1e9b: 0x3902, 0x1e9c: 0x3a00, 0x1e9d: 0x3904, + 0x1e9e: 0x3a02, 0x1e9f: 0x3a04, 0x1ea0: 0x3a08, 0x1ea1: 0x38e6, 0x1ea2: 0x391e, 0x1ea3: 0x3922, + 0x1ea4: 0x38e2, 0x1ea5: 0x3a0c, 0x1ea6: 0x2321, 0x1ea7: 0x3a10, 0x1ea8: 0x3a14, 0x1ea9: 0x3a18, + 0x1eaa: 0x3a1c, 0x1eab: 0x3a20, 0x1eac: 0x3a24, 0x1ead: 0x3a28, 0x1eae: 0x3a2c, 0x1eaf: 0x3a30, + 0x1eb0: 0x3a34, 0x1eb1: 0x2269, 0x1eb2: 0x226d, 0x1eb3: 0x2271, 0x1eb4: 0x2275, 0x1eb5: 0x2279, + 0x1eb6: 0x227d, 0x1eb7: 0x2281, 0x1eb8: 0x2285, 0x1eb9: 0x2289, 0x1eba: 0x228d, 0x1ebb: 0x2291, + 0x1ebc: 0x2295, 0x1ebd: 0x2299, 0x1ebe: 0x229d, 0x1ebf: 0x22a1, + // Block 0x7b, offset 0x1ec0 + 0x1ec0: 0x22a5, 0x1ec1: 0x22a9, 0x1ec2: 0x22ad, 0x1ec3: 0x22b1, 0x1ec4: 0x22b5, 0x1ec5: 0x22b9, + 0x1ec6: 0x22bd, 0x1ec7: 0x22c1, 0x1ec8: 0x22c5, 0x1ec9: 0x22c9, 0x1eca: 0x22cd, 0x1ecb: 0x22d1, + 0x1ecc: 0x22d5, 0x1ecd: 0x22d9, 0x1ece: 0x22dd, 0x1ecf: 0x22e1, 0x1ed0: 0x22e5, 0x1ed1: 0x22e9, + 0x1ed2: 0x22ed, 0x1ed3: 0x22f1, 0x1ed4: 0x22f5, 0x1ed5: 0x22f9, 0x1ed6: 0x22fd, 0x1ed7: 0x2301, + 0x1ed8: 0x2305, 0x1ed9: 0x2309, 0x1eda: 0x230d, 0x1edb: 0x2311, 0x1edc: 0x2315, 0x1edd: 0x3a38, + 0x1ede: 0x3a3c, 0x1edf: 0x3a40, 0x1ee0: 0x1e04, 0x1ee1: 0x1d38, 0x1ee2: 0x1d3c, 0x1ee3: 0x1d40, + 0x1ee4: 0x1d44, 0x1ee5: 0x1d48, 0x1ee6: 0x1d4c, 0x1ee7: 0x1d50, 0x1ee8: 0x1d54, 0x1ee9: 0x1d58, + 0x1eea: 0x1d5c, 0x1eeb: 0x1d60, 0x1eec: 0x1d64, 0x1eed: 0x1d68, 0x1eee: 0x1d6c, 0x1eef: 0x1d70, + 0x1ef0: 0x1d74, 0x1ef1: 0x1d78, 0x1ef2: 0x1d7c, 0x1ef3: 0x1d80, 0x1ef4: 0x1d84, 0x1ef5: 0x1d88, + 0x1ef6: 0x1d8c, 0x1ef7: 0x1d90, 0x1ef8: 0x1d94, 0x1ef9: 0x1d98, 0x1efa: 0x1d9c, 0x1efb: 0x1da0, + 0x1efc: 0x1da4, 0x1efd: 0x1da8, 0x1efe: 0x1dac, + // Block 0x7c, offset 0x1f00 + 0x1f02: 0x1db0, 0x1f03: 0x1db4, 0x1f04: 0x1db8, 0x1f05: 0x1dbc, + 0x1f06: 0x1dc0, 0x1f07: 0x1dc4, 0x1f0a: 0x1dc8, 0x1f0b: 0x1dcc, + 0x1f0c: 0x1dd0, 0x1f0d: 0x1dd4, 0x1f0e: 0x1dd8, 0x1f0f: 0x1ddc, + 0x1f12: 0x1de0, 0x1f13: 0x1de4, 0x1f14: 0x1de8, 0x1f15: 0x1dec, 0x1f16: 0x1df0, 0x1f17: 0x1df4, + 0x1f1a: 0x1df8, 0x1f1b: 0x1dfc, 0x1f1c: 0x1e00, + 0x1f20: 0x3a44, 0x1f21: 0x3a47, 0x1f22: 0x3a4a, 0x1f23: 0x0009, + 0x1f24: 0x3a4d, 0x1f25: 0x3a50, 0x1f26: 0x3a53, 0x1f28: 0x3a57, 0x1f29: 0x3a5b, + 0x1f2a: 0x3a5f, 0x1f2b: 0x3a63, 0x1f2c: 0x3a67, 0x1f2d: 0x3a6b, 0x1f2e: 0x3a6f, + // Block 0x7d, offset 0x1f40 + 0x1f5a: 0x3a73, 0x1f5c: 0x3a7c, + 0x1f6b: 0x3a85, + // Block 0x7e, offset 0x1f80 + 0x1f9e: 0x3a8e, 0x1f9f: 0x3a97, 0x1fa0: 0x3aa0, 0x1fa1: 0x3aad, 0x1fa2: 0x3aba, 0x1fa3: 0x3ac7, + 0x1fa4: 0x3ad4, + // Block 0x7f, offset 0x1fc0 + 0x1ffb: 0x3ae1, + 0x1ffc: 0x3aea, 0x1ffd: 0x3af3, 0x1ffe: 0x3b00, 0x1fff: 0x3b0d, + // Block 0x80, offset 0x2000 + 0x2000: 0x3b1a, + // Block 0x81, offset 0x2040 + 0x2040: 0x0906, 0x2041: 0x090b, 0x2042: 0x14ad, 0x2043: 0x090d, 0x2044: 0x090f, 0x2045: 0x14d9, + 0x2046: 0x0914, 0x2047: 0x0916, 0x2048: 0x0918, 0x2049: 0x091a, 0x204a: 0x091c, 0x204b: 0x091e, + 0x204c: 0x0920, 0x204d: 0x0922, 0x204e: 0x0924, 0x204f: 0x0929, 0x2050: 0x14c8, 0x2051: 0x092b, + 0x2052: 0x17f6, 0x2053: 0x092d, 0x2054: 0x092f, 0x2055: 0x155f, 0x2056: 0x0931, 0x2057: 0x1570, + 0x2058: 0x17f8, 0x2059: 0x14d4, 0x205a: 0x0007, 0x205b: 0x093d, 0x205c: 0x0984, 0x205d: 0x093f, + 0x205e: 0x0941, 0x205f: 0x098c, 0x2060: 0x094c, 0x2061: 0x0494, 0x2062: 0x097c, 0x2063: 0x0499, + 0x2064: 0x094e, 0x2065: 0x04c5, 0x2066: 0x0950, 0x2067: 0x14a0, 0x2068: 0x001e, 0x2069: 0x0960, + 0x206a: 0x17fa, 0x206b: 0x049b, 0x206c: 0x02c8, 0x206d: 0x0962, 0x206e: 0x0964, 0x206f: 0x096d, + 0x2070: 0x04a6, 0x2071: 0x04c7, 0x2072: 0x04a8, 0x2073: 0x09df, 0x2074: 0x0906, 0x2075: 0x090b, + 0x2076: 0x14ad, 0x2077: 0x090d, 0x2078: 0x090f, 0x2079: 0x14d9, 0x207a: 0x0914, 0x207b: 0x0916, + 0x207c: 0x0918, 0x207d: 0x091a, 0x207e: 0x091c, 0x207f: 0x091e, + // Block 0x82, offset 0x2080 + 0x2080: 0x0920, 0x2081: 0x0922, 0x2082: 0x0924, 0x2083: 0x0929, 0x2084: 0x14c8, 0x2085: 0x092b, + 0x2086: 0x17f6, 0x2087: 0x092d, 0x2088: 0x092f, 0x2089: 0x155f, 0x208a: 0x0931, 0x208b: 0x1570, + 0x208c: 0x17f8, 0x208d: 0x14d4, 0x208e: 0x0007, 0x208f: 0x093d, 0x2090: 0x0984, 0x2091: 0x093f, + 0x2092: 0x0941, 0x2093: 0x098c, 0x2094: 0x094c, 0x2096: 0x097c, 0x2097: 0x0499, + 0x2098: 0x094e, 0x2099: 0x04c5, 0x209a: 0x0950, 0x209b: 0x14a0, 0x209c: 0x001e, 0x209d: 0x0960, + 0x209e: 0x17fa, 0x209f: 0x049b, 0x20a0: 0x02c8, 0x20a1: 0x0962, 0x20a2: 0x0964, 0x20a3: 0x096d, + 0x20a4: 0x04a6, 0x20a5: 0x04c7, 0x20a6: 0x04a8, 0x20a7: 0x09df, 0x20a8: 0x0906, 0x20a9: 0x090b, + 0x20aa: 0x14ad, 0x20ab: 0x090d, 0x20ac: 0x090f, 0x20ad: 0x14d9, 0x20ae: 0x0914, 0x20af: 0x0916, + 0x20b0: 0x0918, 0x20b1: 0x091a, 0x20b2: 0x091c, 0x20b3: 0x091e, 0x20b4: 0x0920, 0x20b5: 0x0922, + 0x20b6: 0x0924, 0x20b7: 0x0929, 0x20b8: 0x14c8, 0x20b9: 0x092b, 0x20ba: 0x17f6, 0x20bb: 0x092d, + 0x20bc: 0x092f, 0x20bd: 0x155f, 0x20be: 0x0931, 0x20bf: 0x1570, + // Block 0x83, offset 0x20c0 + 0x20c0: 0x17f8, 0x20c1: 0x14d4, 0x20c2: 0x0007, 0x20c3: 0x093d, 0x20c4: 0x0984, 0x20c5: 0x093f, + 0x20c6: 0x0941, 0x20c7: 0x098c, 0x20c8: 0x094c, 0x20c9: 0x0494, 0x20ca: 0x097c, 0x20cb: 0x0499, + 0x20cc: 0x094e, 0x20cd: 0x04c5, 0x20ce: 0x0950, 0x20cf: 0x14a0, 0x20d0: 0x001e, 0x20d1: 0x0960, + 0x20d2: 0x17fa, 0x20d3: 0x049b, 0x20d4: 0x02c8, 0x20d5: 0x0962, 0x20d6: 0x0964, 0x20d7: 0x096d, + 0x20d8: 0x04a6, 0x20d9: 0x04c7, 0x20da: 0x04a8, 0x20db: 0x09df, 0x20dc: 0x0906, + 0x20de: 0x14ad, 0x20df: 0x090d, 0x20e2: 0x0914, + 0x20e5: 0x091a, 0x20e6: 0x091c, 0x20e9: 0x0922, + 0x20ea: 0x0924, 0x20eb: 0x0929, 0x20ec: 0x14c8, 0x20ee: 0x17f6, 0x20ef: 0x092d, + 0x20f0: 0x092f, 0x20f1: 0x155f, 0x20f2: 0x0931, 0x20f3: 0x1570, 0x20f4: 0x17f8, 0x20f5: 0x14d4, + 0x20f6: 0x0007, 0x20f7: 0x093d, 0x20f8: 0x0984, 0x20f9: 0x093f, 0x20fb: 0x098c, + 0x20fd: 0x0494, 0x20fe: 0x097c, 0x20ff: 0x0499, + // Block 0x84, offset 0x2100 + 0x2100: 0x094e, 0x2101: 0x04c5, 0x2102: 0x0950, 0x2103: 0x14a0, 0x2105: 0x0960, + 0x2106: 0x17fa, 0x2107: 0x049b, 0x2108: 0x02c8, 0x2109: 0x0962, 0x210a: 0x0964, 0x210b: 0x096d, + 0x210c: 0x04a6, 0x210d: 0x04c7, 0x210e: 0x04a8, 0x210f: 0x09df, 0x2110: 0x0906, 0x2111: 0x090b, + 0x2112: 0x14ad, 0x2113: 0x090d, 0x2114: 0x090f, 0x2115: 0x14d9, 0x2116: 0x0914, 0x2117: 0x0916, + 0x2118: 0x0918, 0x2119: 0x091a, 0x211a: 0x091c, 0x211b: 0x091e, 0x211c: 0x0920, 0x211d: 0x0922, + 0x211e: 0x0924, 0x211f: 0x0929, 0x2120: 0x14c8, 0x2121: 0x092b, 0x2122: 0x17f6, 0x2123: 0x092d, + 0x2124: 0x092f, 0x2125: 0x155f, 0x2126: 0x0931, 0x2127: 0x1570, 0x2128: 0x17f8, 0x2129: 0x14d4, + 0x212a: 0x0007, 0x212b: 0x093d, 0x212c: 0x0984, 0x212d: 0x093f, 0x212e: 0x0941, 0x212f: 0x098c, + 0x2130: 0x094c, 0x2131: 0x0494, 0x2132: 0x097c, 0x2133: 0x0499, 0x2134: 0x094e, 0x2135: 0x04c5, + 0x2136: 0x0950, 0x2137: 0x14a0, 0x2138: 0x001e, 0x2139: 0x0960, 0x213a: 0x17fa, 0x213b: 0x049b, + 0x213c: 0x02c8, 0x213d: 0x0962, 0x213e: 0x0964, 0x213f: 0x096d, + // Block 0x85, offset 0x2140 + 0x2140: 0x04a6, 0x2141: 0x04c7, 0x2142: 0x04a8, 0x2143: 0x09df, 0x2144: 0x0906, 0x2145: 0x090b, + 0x2147: 0x090d, 0x2148: 0x090f, 0x2149: 0x14d9, 0x214a: 0x0914, + 0x214d: 0x091a, 0x214e: 0x091c, 0x214f: 0x091e, 0x2150: 0x0920, 0x2151: 0x0922, + 0x2152: 0x0924, 0x2153: 0x0929, 0x2154: 0x14c8, 0x2156: 0x17f6, 0x2157: 0x092d, + 0x2158: 0x092f, 0x2159: 0x155f, 0x215a: 0x0931, 0x215b: 0x1570, 0x215c: 0x17f8, + 0x215e: 0x0007, 0x215f: 0x093d, 0x2160: 0x0984, 0x2161: 0x093f, 0x2162: 0x0941, 0x2163: 0x098c, + 0x2164: 0x094c, 0x2165: 0x0494, 0x2166: 0x097c, 0x2167: 0x0499, 0x2168: 0x094e, 0x2169: 0x04c5, + 0x216a: 0x0950, 0x216b: 0x14a0, 0x216c: 0x001e, 0x216d: 0x0960, 0x216e: 0x17fa, 0x216f: 0x049b, + 0x2170: 0x02c8, 0x2171: 0x0962, 0x2172: 0x0964, 0x2173: 0x096d, 0x2174: 0x04a6, 0x2175: 0x04c7, + 0x2176: 0x04a8, 0x2177: 0x09df, 0x2178: 0x0906, 0x2179: 0x090b, 0x217b: 0x090d, + 0x217c: 0x090f, 0x217d: 0x14d9, 0x217e: 0x0914, + // Block 0x86, offset 0x2180 + 0x2180: 0x0918, 0x2181: 0x091a, 0x2182: 0x091c, 0x2183: 0x091e, 0x2184: 0x0920, + 0x2186: 0x0924, 0x218a: 0x17f6, 0x218b: 0x092d, + 0x218c: 0x092f, 0x218d: 0x155f, 0x218e: 0x0931, 0x218f: 0x1570, 0x2190: 0x17f8, + 0x2192: 0x0007, 0x2193: 0x093d, 0x2194: 0x0984, 0x2195: 0x093f, 0x2196: 0x0941, 0x2197: 0x098c, + 0x2198: 0x094c, 0x2199: 0x0494, 0x219a: 0x097c, 0x219b: 0x0499, 0x219c: 0x094e, 0x219d: 0x04c5, + 0x219e: 0x0950, 0x219f: 0x14a0, 0x21a0: 0x001e, 0x21a1: 0x0960, 0x21a2: 0x17fa, 0x21a3: 0x049b, + 0x21a4: 0x02c8, 0x21a5: 0x0962, 0x21a6: 0x0964, 0x21a7: 0x096d, 0x21a8: 0x04a6, 0x21a9: 0x04c7, + 0x21aa: 0x04a8, 0x21ab: 0x09df, 0x21ac: 0x0906, 0x21ad: 0x090b, 0x21ae: 0x14ad, 0x21af: 0x090d, + 0x21b0: 0x090f, 0x21b1: 0x14d9, 0x21b2: 0x0914, 0x21b3: 0x0916, 0x21b4: 0x0918, 0x21b5: 0x091a, + 0x21b6: 0x091c, 0x21b7: 0x091e, 0x21b8: 0x0920, 0x21b9: 0x0922, 0x21ba: 0x0924, 0x21bb: 0x0929, + 0x21bc: 0x14c8, 0x21bd: 0x092b, 0x21be: 0x17f6, 0x21bf: 0x092d, + // Block 0x87, offset 0x21c0 + 0x21c0: 0x092f, 0x21c1: 0x155f, 0x21c2: 0x0931, 0x21c3: 0x1570, 0x21c4: 0x17f8, 0x21c5: 0x14d4, + 0x21c6: 0x0007, 0x21c7: 0x093d, 0x21c8: 0x0984, 0x21c9: 0x093f, 0x21ca: 0x0941, 0x21cb: 0x098c, + 0x21cc: 0x094c, 0x21cd: 0x0494, 0x21ce: 0x097c, 0x21cf: 0x0499, 0x21d0: 0x094e, 0x21d1: 0x04c5, + 0x21d2: 0x0950, 0x21d3: 0x14a0, 0x21d4: 0x001e, 0x21d5: 0x0960, 0x21d6: 0x17fa, 0x21d7: 0x049b, + 0x21d8: 0x02c8, 0x21d9: 0x0962, 0x21da: 0x0964, 0x21db: 0x096d, 0x21dc: 0x04a6, 0x21dd: 0x04c7, + 0x21de: 0x04a8, 0x21df: 0x09df, 0x21e0: 0x0906, 0x21e1: 0x090b, 0x21e2: 0x14ad, 0x21e3: 0x090d, + 0x21e4: 0x090f, 0x21e5: 0x14d9, 0x21e6: 0x0914, 0x21e7: 0x0916, 0x21e8: 0x0918, 0x21e9: 0x091a, + 0x21ea: 0x091c, 0x21eb: 0x091e, 0x21ec: 0x0920, 0x21ed: 0x0922, 0x21ee: 0x0924, 0x21ef: 0x0929, + 0x21f0: 0x14c8, 0x21f1: 0x092b, 0x21f2: 0x17f6, 0x21f3: 0x092d, 0x21f4: 0x092f, 0x21f5: 0x155f, + 0x21f6: 0x0931, 0x21f7: 0x1570, 0x21f8: 0x17f8, 0x21f9: 0x14d4, 0x21fa: 0x0007, 0x21fb: 0x093d, + 0x21fc: 0x0984, 0x21fd: 0x093f, 0x21fe: 0x0941, 0x21ff: 0x098c, + // Block 0x88, offset 0x2200 + 0x2200: 0x094c, 0x2201: 0x0494, 0x2202: 0x097c, 0x2203: 0x0499, 0x2204: 0x094e, 0x2205: 0x04c5, + 0x2206: 0x0950, 0x2207: 0x14a0, 0x2208: 0x001e, 0x2209: 0x0960, 0x220a: 0x17fa, 0x220b: 0x049b, + 0x220c: 0x02c8, 0x220d: 0x0962, 0x220e: 0x0964, 0x220f: 0x096d, 0x2210: 0x04a6, 0x2211: 0x04c7, + 0x2212: 0x04a8, 0x2213: 0x09df, 0x2214: 0x0906, 0x2215: 0x090b, 0x2216: 0x14ad, 0x2217: 0x090d, + 0x2218: 0x090f, 0x2219: 0x14d9, 0x221a: 0x0914, 0x221b: 0x0916, 0x221c: 0x0918, 0x221d: 0x091a, + 0x221e: 0x091c, 0x221f: 0x091e, 0x2220: 0x0920, 0x2221: 0x0922, 0x2222: 0x0924, 0x2223: 0x0929, + 0x2224: 0x14c8, 0x2225: 0x092b, 0x2226: 0x17f6, 0x2227: 0x092d, 0x2228: 0x092f, 0x2229: 0x155f, + 0x222a: 0x0931, 0x222b: 0x1570, 0x222c: 0x17f8, 0x222d: 0x14d4, 0x222e: 0x0007, 0x222f: 0x093d, + 0x2230: 0x0984, 0x2231: 0x093f, 0x2232: 0x0941, 0x2233: 0x098c, 0x2234: 0x094c, 0x2235: 0x0494, + 0x2236: 0x097c, 0x2237: 0x0499, 0x2238: 0x094e, 0x2239: 0x04c5, 0x223a: 0x0950, 0x223b: 0x14a0, + 0x223c: 0x001e, 0x223d: 0x0960, 0x223e: 0x17fa, 0x223f: 0x049b, + // Block 0x89, offset 0x2240 + 0x2240: 0x02c8, 0x2241: 0x0962, 0x2242: 0x0964, 0x2243: 0x096d, 0x2244: 0x04a6, 0x2245: 0x04c7, + 0x2246: 0x04a8, 0x2247: 0x09df, 0x2248: 0x0906, 0x2249: 0x090b, 0x224a: 0x14ad, 0x224b: 0x090d, + 0x224c: 0x090f, 0x224d: 0x14d9, 0x224e: 0x0914, 0x224f: 0x0916, 0x2250: 0x0918, 0x2251: 0x091a, + 0x2252: 0x091c, 0x2253: 0x091e, 0x2254: 0x0920, 0x2255: 0x0922, 0x2256: 0x0924, 0x2257: 0x0929, + 0x2258: 0x14c8, 0x2259: 0x092b, 0x225a: 0x17f6, 0x225b: 0x092d, 0x225c: 0x092f, 0x225d: 0x155f, + 0x225e: 0x0931, 0x225f: 0x1570, 0x2260: 0x17f8, 0x2261: 0x14d4, 0x2262: 0x0007, 0x2263: 0x093d, + 0x2264: 0x0984, 0x2265: 0x093f, 0x2266: 0x0941, 0x2267: 0x098c, 0x2268: 0x094c, 0x2269: 0x0494, + 0x226a: 0x097c, 0x226b: 0x0499, 0x226c: 0x094e, 0x226d: 0x04c5, 0x226e: 0x0950, 0x226f: 0x14a0, + 0x2270: 0x001e, 0x2271: 0x0960, 0x2272: 0x17fa, 0x2273: 0x049b, 0x2274: 0x02c8, 0x2275: 0x0962, + 0x2276: 0x0964, 0x2277: 0x096d, 0x2278: 0x04a6, 0x2279: 0x04c7, 0x227a: 0x04a8, 0x227b: 0x09df, + 0x227c: 0x0906, 0x227d: 0x090b, 0x227e: 0x14ad, 0x227f: 0x090d, + // Block 0x8a, offset 0x2280 + 0x2280: 0x090f, 0x2281: 0x14d9, 0x2282: 0x0914, 0x2283: 0x0916, 0x2284: 0x0918, 0x2285: 0x091a, + 0x2286: 0x091c, 0x2287: 0x091e, 0x2288: 0x0920, 0x2289: 0x0922, 0x228a: 0x0924, 0x228b: 0x0929, + 0x228c: 0x14c8, 0x228d: 0x092b, 0x228e: 0x17f6, 0x228f: 0x092d, 0x2290: 0x092f, 0x2291: 0x155f, + 0x2292: 0x0931, 0x2293: 0x1570, 0x2294: 0x17f8, 0x2295: 0x14d4, 0x2296: 0x0007, 0x2297: 0x093d, + 0x2298: 0x0984, 0x2299: 0x093f, 0x229a: 0x0941, 0x229b: 0x098c, 0x229c: 0x094c, 0x229d: 0x0494, + 0x229e: 0x097c, 0x229f: 0x0499, 0x22a0: 0x094e, 0x22a1: 0x04c5, 0x22a2: 0x0950, 0x22a3: 0x14a0, + 0x22a4: 0x001e, 0x22a5: 0x0960, 0x22a6: 0x17fa, 0x22a7: 0x049b, 0x22a8: 0x02c8, 0x22a9: 0x0962, + 0x22aa: 0x0964, 0x22ab: 0x096d, 0x22ac: 0x04a6, 0x22ad: 0x04c7, 0x22ae: 0x04a8, 0x22af: 0x09df, + 0x22b0: 0x0906, 0x22b1: 0x090b, 0x22b2: 0x14ad, 0x22b3: 0x090d, 0x22b4: 0x090f, 0x22b5: 0x14d9, + 0x22b6: 0x0914, 0x22b7: 0x0916, 0x22b8: 0x0918, 0x22b9: 0x091a, 0x22ba: 0x091c, 0x22bb: 0x091e, + 0x22bc: 0x0920, 0x22bd: 0x0922, 0x22be: 0x0924, 0x22bf: 0x0929, + // Block 0x8b, offset 0x22c0 + 0x22c0: 0x14c8, 0x22c1: 0x092b, 0x22c2: 0x17f6, 0x22c3: 0x092d, 0x22c4: 0x092f, 0x22c5: 0x155f, + 0x22c6: 0x0931, 0x22c7: 0x1570, 0x22c8: 0x17f8, 0x22c9: 0x14d4, 0x22ca: 0x0007, 0x22cb: 0x093d, + 0x22cc: 0x0984, 0x22cd: 0x093f, 0x22ce: 0x0941, 0x22cf: 0x098c, 0x22d0: 0x094c, 0x22d1: 0x0494, + 0x22d2: 0x097c, 0x22d3: 0x0499, 0x22d4: 0x094e, 0x22d5: 0x04c5, 0x22d6: 0x0950, 0x22d7: 0x14a0, + 0x22d8: 0x001e, 0x22d9: 0x0960, 0x22da: 0x17fa, 0x22db: 0x049b, 0x22dc: 0x02c8, 0x22dd: 0x0962, + 0x22de: 0x0964, 0x22df: 0x096d, 0x22e0: 0x04a6, 0x22e1: 0x04c7, 0x22e2: 0x04a8, 0x22e3: 0x09df, + 0x22e4: 0x3b27, 0x22e5: 0x3b2a, 0x22e8: 0x3b2d, 0x22e9: 0x3b30, + 0x22ea: 0x14eb, 0x22eb: 0x3b33, 0x22ec: 0x3b36, 0x22ed: 0x3b39, 0x22ee: 0x3b3c, 0x22ef: 0x057b, + 0x22f0: 0x3b3f, 0x22f1: 0x3b42, 0x22f2: 0x3b45, 0x22f3: 0x3b48, 0x22f4: 0x3b4b, 0x22f5: 0x3b4e, + 0x22f6: 0x3b51, 0x22f7: 0x14ee, 0x22f8: 0x3b54, 0x22f9: 0x057b, 0x22fa: 0x0581, 0x22fb: 0x3b57, + 0x22fc: 0x055f, 0x22fd: 0x3b5a, 0x22fe: 0x3b5d, 0x22ff: 0x3b60, + // Block 0x8c, offset 0x2300 + 0x2300: 0x14d6, 0x2301: 0x3b63, 0x2302: 0x3b67, 0x2303: 0x0559, 0x2304: 0x0973, 0x2305: 0x0976, + 0x2306: 0x057e, 0x2307: 0x3b6a, 0x2308: 0x3b6d, 0x2309: 0x055c, 0x230a: 0x12fd, 0x230b: 0x0572, + 0x230c: 0x3b70, 0x230d: 0x0015, 0x230e: 0x3b73, 0x230f: 0x3b76, 0x2310: 0x3b79, 0x2311: 0x056f, + 0x2312: 0x0575, 0x2313: 0x0578, 0x2314: 0x3b7c, 0x2315: 0x3b7f, 0x2316: 0x3b82, 0x2317: 0x056c, + 0x2318: 0x0979, 0x2319: 0x3b85, 0x231a: 0x3b88, 0x231b: 0x3b8b, 0x231c: 0x057e, 0x231d: 0x055c, + 0x231e: 0x0572, 0x231f: 0x056c, 0x2320: 0x0575, 0x2321: 0x056f, 0x2322: 0x3b2d, 0x2323: 0x3b30, + 0x2324: 0x14eb, 0x2325: 0x3b33, 0x2326: 0x3b36, 0x2327: 0x3b39, 0x2328: 0x3b3c, 0x2329: 0x057b, + 0x232a: 0x3b3f, 0x232b: 0x3b42, 0x232c: 0x3b45, 0x232d: 0x3b48, 0x232e: 0x3b4b, 0x232f: 0x3b4e, + 0x2330: 0x3b51, 0x2331: 0x14ee, 0x2332: 0x3b54, 0x2333: 0x057b, 0x2334: 0x0581, 0x2335: 0x3b57, + 0x2336: 0x055f, 0x2337: 0x3b5a, 0x2338: 0x3b5d, 0x2339: 0x3b60, 0x233a: 0x14d6, 0x233b: 0x3b63, + 0x233c: 0x3b67, 0x233d: 0x0559, 0x233e: 0x0973, 0x233f: 0x0976, + // Block 0x8d, offset 0x2340 + 0x2340: 0x057e, 0x2341: 0x3b6a, 0x2342: 0x3b6d, 0x2343: 0x055c, 0x2344: 0x12fd, 0x2345: 0x0572, + 0x2346: 0x3b70, 0x2347: 0x0015, 0x2348: 0x3b73, 0x2349: 0x3b76, 0x234a: 0x3b79, 0x234b: 0x056f, + 0x234c: 0x0575, 0x234d: 0x0578, 0x234e: 0x3b7c, 0x234f: 0x3b7f, 0x2350: 0x3b82, 0x2351: 0x056c, + 0x2352: 0x0979, 0x2353: 0x3b85, 0x2354: 0x3b88, 0x2355: 0x3b8b, 0x2356: 0x057e, 0x2357: 0x055c, + 0x2358: 0x0572, 0x2359: 0x056c, 0x235a: 0x0575, 0x235b: 0x056f, 0x235c: 0x3b2d, 0x235d: 0x3b30, + 0x235e: 0x14eb, 0x235f: 0x3b33, 0x2360: 0x3b36, 0x2361: 0x3b39, 0x2362: 0x3b3c, 0x2363: 0x057b, + 0x2364: 0x3b3f, 0x2365: 0x3b42, 0x2366: 0x3b45, 0x2367: 0x3b48, 0x2368: 0x3b4b, 0x2369: 0x3b4e, + 0x236a: 0x3b51, 0x236b: 0x14ee, 0x236c: 0x3b54, 0x236d: 0x057b, 0x236e: 0x0581, 0x236f: 0x3b57, + 0x2370: 0x055f, 0x2371: 0x3b5a, 0x2372: 0x3b5d, 0x2373: 0x3b60, 0x2374: 0x14d6, 0x2375: 0x3b63, + 0x2376: 0x3b67, 0x2377: 0x0559, 0x2378: 0x0973, 0x2379: 0x0976, 0x237a: 0x057e, 0x237b: 0x3b6a, + 0x237c: 0x3b6d, 0x237d: 0x055c, 0x237e: 0x12fd, 0x237f: 0x0572, + // Block 0x8e, offset 0x2380 + 0x2380: 0x3b70, 0x2381: 0x0015, 0x2382: 0x3b73, 0x2383: 0x3b76, 0x2384: 0x3b79, 0x2385: 0x056f, + 0x2386: 0x0575, 0x2387: 0x0578, 0x2388: 0x3b7c, 0x2389: 0x3b7f, 0x238a: 0x3b82, 0x238b: 0x056c, + 0x238c: 0x0979, 0x238d: 0x3b85, 0x238e: 0x3b88, 0x238f: 0x3b8b, 0x2390: 0x057e, 0x2391: 0x055c, + 0x2392: 0x0572, 0x2393: 0x056c, 0x2394: 0x0575, 0x2395: 0x056f, 0x2396: 0x3b2d, 0x2397: 0x3b30, + 0x2398: 0x14eb, 0x2399: 0x3b33, 0x239a: 0x3b36, 0x239b: 0x3b39, 0x239c: 0x3b3c, 0x239d: 0x057b, + 0x239e: 0x3b3f, 0x239f: 0x3b42, 0x23a0: 0x3b45, 0x23a1: 0x3b48, 0x23a2: 0x3b4b, 0x23a3: 0x3b4e, + 0x23a4: 0x3b51, 0x23a5: 0x14ee, 0x23a6: 0x3b54, 0x23a7: 0x057b, 0x23a8: 0x0581, 0x23a9: 0x3b57, + 0x23aa: 0x055f, 0x23ab: 0x3b5a, 0x23ac: 0x3b5d, 0x23ad: 0x3b60, 0x23ae: 0x14d6, 0x23af: 0x3b63, + 0x23b0: 0x3b67, 0x23b1: 0x0559, 0x23b2: 0x0973, 0x23b3: 0x0976, 0x23b4: 0x057e, 0x23b5: 0x3b6a, + 0x23b6: 0x3b6d, 0x23b7: 0x055c, 0x23b8: 0x12fd, 0x23b9: 0x0572, 0x23ba: 0x3b70, 0x23bb: 0x0015, + 0x23bc: 0x3b73, 0x23bd: 0x3b76, 0x23be: 0x3b79, 0x23bf: 0x056f, + // Block 0x8f, offset 0x23c0 + 0x23c0: 0x0575, 0x23c1: 0x0578, 0x23c2: 0x3b7c, 0x23c3: 0x3b7f, 0x23c4: 0x3b82, 0x23c5: 0x056c, + 0x23c6: 0x0979, 0x23c7: 0x3b85, 0x23c8: 0x3b88, 0x23c9: 0x3b8b, 0x23ca: 0x057e, 0x23cb: 0x055c, + 0x23cc: 0x0572, 0x23cd: 0x056c, 0x23ce: 0x0575, 0x23cf: 0x056f, 0x23d0: 0x3b2d, 0x23d1: 0x3b30, + 0x23d2: 0x14eb, 0x23d3: 0x3b33, 0x23d4: 0x3b36, 0x23d5: 0x3b39, 0x23d6: 0x3b3c, 0x23d7: 0x057b, + 0x23d8: 0x3b3f, 0x23d9: 0x3b42, 0x23da: 0x3b45, 0x23db: 0x3b48, 0x23dc: 0x3b4b, 0x23dd: 0x3b4e, + 0x23de: 0x3b51, 0x23df: 0x14ee, 0x23e0: 0x3b54, 0x23e1: 0x057b, 0x23e2: 0x0581, 0x23e3: 0x3b57, + 0x23e4: 0x055f, 0x23e5: 0x3b5a, 0x23e6: 0x3b5d, 0x23e7: 0x3b60, 0x23e8: 0x14d6, 0x23e9: 0x3b63, + 0x23ea: 0x3b67, 0x23eb: 0x0559, 0x23ec: 0x0973, 0x23ed: 0x0976, 0x23ee: 0x057e, 0x23ef: 0x3b6a, + 0x23f0: 0x3b6d, 0x23f1: 0x055c, 0x23f2: 0x12fd, 0x23f3: 0x0572, 0x23f4: 0x3b70, 0x23f5: 0x0015, + 0x23f6: 0x3b73, 0x23f7: 0x3b76, 0x23f8: 0x3b79, 0x23f9: 0x056f, 0x23fa: 0x0575, 0x23fb: 0x0578, + 0x23fc: 0x3b7c, 0x23fd: 0x3b7f, 0x23fe: 0x3b82, 0x23ff: 0x056c, + // Block 0x90, offset 0x2400 + 0x2400: 0x0979, 0x2401: 0x3b85, 0x2402: 0x3b88, 0x2403: 0x3b8b, 0x2404: 0x057e, 0x2405: 0x055c, + 0x2406: 0x0572, 0x2407: 0x056c, 0x2408: 0x0575, 0x2409: 0x056f, 0x240a: 0x3b8f, 0x240b: 0x3b92, + 0x240e: 0x1486, 0x240f: 0x001c, 0x2410: 0x000d, 0x2411: 0x000f, + 0x2412: 0x1488, 0x2413: 0x148a, 0x2414: 0x148c, 0x2415: 0x148e, 0x2416: 0x1490, 0x2417: 0x1492, + 0x2418: 0x1486, 0x2419: 0x001c, 0x241a: 0x000d, 0x241b: 0x000f, 0x241c: 0x1488, 0x241d: 0x148a, + 0x241e: 0x148c, 0x241f: 0x148e, 0x2420: 0x1490, 0x2421: 0x1492, 0x2422: 0x1486, 0x2423: 0x001c, + 0x2424: 0x000d, 0x2425: 0x000f, 0x2426: 0x1488, 0x2427: 0x148a, 0x2428: 0x148c, 0x2429: 0x148e, + 0x242a: 0x1490, 0x242b: 0x1492, 0x242c: 0x1486, 0x242d: 0x001c, 0x242e: 0x000d, 0x242f: 0x000f, + 0x2430: 0x1488, 0x2431: 0x148a, 0x2432: 0x148c, 0x2433: 0x148e, 0x2434: 0x1490, 0x2435: 0x1492, + 0x2436: 0x1486, 0x2437: 0x001c, 0x2438: 0x000d, 0x2439: 0x000f, 0x243a: 0x1488, 0x243b: 0x148a, + 0x243c: 0x148c, 0x243d: 0x148e, 0x243e: 0x1490, 0x243f: 0x1492, + // Block 0x91, offset 0x2440 + 0x2440: 0x3b95, 0x2441: 0x3b98, 0x2442: 0x3b9b, 0x2443: 0x3b9e, 0x2444: 0x3ba1, 0x2445: 0x3ba4, + 0x2446: 0x3ba7, 0x2447: 0x3baa, 0x2448: 0x3bad, 0x2449: 0x3bb0, 0x244a: 0x3bb3, + 0x2450: 0x3bb6, 0x2451: 0x3bba, + 0x2452: 0x3bbe, 0x2453: 0x3bc2, 0x2454: 0x3bc6, 0x2455: 0x3bca, 0x2456: 0x3bce, 0x2457: 0x3bd2, + 0x2458: 0x3bd6, 0x2459: 0x3bda, 0x245a: 0x3bde, 0x245b: 0x3be2, 0x245c: 0x3be6, 0x245d: 0x3bea, + 0x245e: 0x3bee, 0x245f: 0x3bf2, 0x2460: 0x3bf6, 0x2461: 0x3bfa, 0x2462: 0x3bfe, 0x2463: 0x3c02, + 0x2464: 0x3c06, 0x2465: 0x3c0a, 0x2466: 0x3c0e, 0x2467: 0x3c12, 0x2468: 0x3c16, 0x2469: 0x3c1a, + 0x246a: 0x3c1e, 0x246b: 0x14ad, 0x246c: 0x092b, 0x246d: 0x3c26, 0x246e: 0x3c29, + 0x2470: 0x0906, 0x2471: 0x090b, 0x2472: 0x14ad, 0x2473: 0x090d, 0x2474: 0x090f, 0x2475: 0x14d9, + 0x2476: 0x0914, 0x2477: 0x0916, 0x2478: 0x0918, 0x2479: 0x091a, 0x247a: 0x091c, 0x247b: 0x091e, + 0x247c: 0x0920, 0x247d: 0x0922, 0x247e: 0x0924, 0x247f: 0x0929, + // Block 0x92, offset 0x2480 + 0x2480: 0x14c8, 0x2481: 0x092b, 0x2482: 0x17f6, 0x2483: 0x092d, 0x2484: 0x092f, 0x2485: 0x155f, + 0x2486: 0x0931, 0x2487: 0x1570, 0x2488: 0x17f8, 0x2489: 0x14d4, 0x248a: 0x3c2c, 0x248b: 0x293d, + 0x248c: 0x3c2f, 0x248d: 0x3c32, 0x248e: 0x3c35, 0x248f: 0x3c39, + // Block 0x93, offset 0x24c0 + 0x24d0: 0x3c3c, + // Block 0x94, offset 0x2500 + 0x2500: 0x3c3f, 0x2501: 0x3c46, 0x2502: 0x2291, + 0x2510: 0x1922, 0x2511: 0x3c4d, + 0x2512: 0x3c51, 0x2513: 0x1cb3, 0x2514: 0x183e, 0x2515: 0x3c55, 0x2516: 0x3c59, 0x2517: 0x1ed0, + 0x2518: 0x3c5d, 0x2519: 0x3c61, 0x251a: 0x3c65, 0x251b: 0x2d49, 0x251c: 0x3c69, 0x251d: 0x3c6d, + 0x251e: 0x3c71, 0x251f: 0x3c75, 0x2520: 0x3c79, 0x2521: 0x3c7d, 0x2522: 0x19b2, 0x2523: 0x3c81, + 0x2524: 0x3c85, 0x2525: 0x3c89, 0x2526: 0x3c8d, 0x2527: 0x3c91, 0x2528: 0x3c95, 0x2529: 0x1826, + 0x252a: 0x1eb0, 0x252b: 0x3c99, 0x252c: 0x21c7, 0x252d: 0x1ebc, 0x252e: 0x21cb, 0x252f: 0x3c9d, + 0x2530: 0x1a92, 0x2531: 0x3ca1, 0x2532: 0x3ca5, 0x2533: 0x3ca9, 0x2534: 0x3cad, 0x2535: 0x3cb1, + 0x2536: 0x2183, 0x2537: 0x194a, 0x2538: 0x3cb5, 0x2539: 0x3cb9, 0x253a: 0x3cbd, + // Block 0x95, offset 0x2540 + 0x2540: 0x3cc1, 0x2541: 0x3ccb, 0x2542: 0x3cd5, 0x2543: 0x3cdf, 0x2544: 0x3ce9, 0x2545: 0x3cf3, + 0x2546: 0x3cfd, 0x2547: 0x3d07, 0x2548: 0x3d11, + 0x2550: 0x3d1b, 0x2551: 0x3d1f, + // Block 0x96, offset 0x2580 + 0x2580: 0x3d23, 0x2581: 0x3d27, 0x2582: 0x3d2b, 0x2583: 0x3d2f, 0x2584: 0x3d34, 0x2585: 0x2eb5, + 0x2586: 0x3d38, 0x2587: 0x3d3c, 0x2588: 0x3d40, 0x2589: 0x3d44, 0x258a: 0x2eb9, 0x258b: 0x3d48, + 0x258c: 0x3d4c, 0x258d: 0x3d50, 0x258e: 0x2ebd, 0x258f: 0x3d55, 0x2590: 0x3d59, 0x2591: 0x3d5d, + 0x2592: 0x3d61, 0x2593: 0x3d66, 0x2594: 0x3d6a, 0x2595: 0x3c71, 0x2596: 0x3d6e, 0x2597: 0x3d73, + 0x2598: 0x3d77, 0x2599: 0x3d7b, 0x259a: 0x3d7f, 0x259b: 0x2f9a, 0x259c: 0x3d83, 0x259d: 0x1866, + 0x259e: 0x3d88, 0x259f: 0x3d8c, 0x25a0: 0x3d90, 0x25a1: 0x3d94, 0x25a2: 0x3cb9, 0x25a3: 0x3d98, + 0x25a4: 0x3d9c, 0x25a5: 0x2fae, 0x25a6: 0x2ec1, 0x25a7: 0x2ec5, 0x25a8: 0x2fb2, 0x25a9: 0x3da0, + 0x25aa: 0x3da4, 0x25ab: 0x2bf1, 0x25ac: 0x3da8, 0x25ad: 0x2ec9, 0x25ae: 0x3dac, 0x25af: 0x3db0, + 0x25b0: 0x3db4, 0x25b1: 0x3db8, 0x25b2: 0x3db8, 0x25b3: 0x3db8, 0x25b4: 0x3dbc, 0x25b5: 0x3dc1, + 0x25b6: 0x3dc5, 0x25b7: 0x3dc9, 0x25b8: 0x3dcd, 0x25b9: 0x3dd2, 0x25ba: 0x3dd6, 0x25bb: 0x3dda, + 0x25bc: 0x3dde, 0x25bd: 0x3de2, 0x25be: 0x3de6, 0x25bf: 0x3dea, + // Block 0x97, offset 0x25c0 + 0x25c0: 0x3dee, 0x25c1: 0x3df2, 0x25c2: 0x3df6, 0x25c3: 0x3dfa, 0x25c4: 0x3dfe, 0x25c5: 0x3e02, + 0x25c6: 0x3e02, 0x25c7: 0x2fba, 0x25c8: 0x3e06, 0x25c9: 0x3e0a, 0x25ca: 0x3e0e, 0x25cb: 0x3e12, + 0x25cc: 0x2ed1, 0x25cd: 0x3e16, 0x25ce: 0x3e1a, 0x25cf: 0x3e1e, 0x25d0: 0x2e39, 0x25d1: 0x3e22, + 0x25d2: 0x3e26, 0x25d3: 0x3e2a, 0x25d4: 0x3e2e, 0x25d5: 0x3e32, 0x25d6: 0x3e36, 0x25d7: 0x3e3a, + 0x25d8: 0x3e3e, 0x25d9: 0x3e42, 0x25da: 0x3e47, 0x25db: 0x3e4b, 0x25dc: 0x3e4f, 0x25dd: 0x3c55, + 0x25de: 0x3e53, 0x25df: 0x3e57, 0x25e0: 0x3e5b, 0x25e1: 0x3e60, 0x25e2: 0x3e65, 0x25e3: 0x3e69, + 0x25e4: 0x3e6d, 0x25e5: 0x3e71, 0x25e6: 0x3e75, 0x25e7: 0x3e79, 0x25e8: 0x3e7d, 0x25e9: 0x3e81, + 0x25ea: 0x3e85, 0x25eb: 0x3e85, 0x25ec: 0x3e89, 0x25ed: 0x3e8e, 0x25ee: 0x3e92, 0x25ef: 0x2be1, + 0x25f0: 0x3e96, 0x25f1: 0x3e9a, 0x25f2: 0x3e9f, 0x25f3: 0x3ea3, 0x25f4: 0x3ea7, 0x25f5: 0x18ce, + 0x25f6: 0x3eab, 0x25f7: 0x3eaf, 0x25f8: 0x18d6, 0x25f9: 0x3eb3, 0x25fa: 0x3eb7, 0x25fb: 0x3ebb, + 0x25fc: 0x3ec0, 0x25fd: 0x3ec4, 0x25fe: 0x3ec9, 0x25ff: 0x3ecd, + // Block 0x98, offset 0x2600 + 0x2600: 0x3ed1, 0x2601: 0x3ed5, 0x2602: 0x3ed9, 0x2603: 0x3edd, 0x2604: 0x3ee1, 0x2605: 0x3ee5, + 0x2606: 0x3ee9, 0x2607: 0x3eed, 0x2608: 0x3ef1, 0x2609: 0x3ef5, 0x260a: 0x3efa, 0x260b: 0x3efe, + 0x260c: 0x3f02, 0x260d: 0x3f06, 0x260e: 0x2b11, 0x260f: 0x3f0a, 0x2610: 0x18fe, 0x2611: 0x3f0f, + 0x2612: 0x3f0f, 0x2613: 0x3f14, 0x2614: 0x3f18, 0x2615: 0x3f18, 0x2616: 0x3f1c, 0x2617: 0x3f20, + 0x2618: 0x3f25, 0x2619: 0x3f2a, 0x261a: 0x3f2e, 0x261b: 0x3f32, 0x261c: 0x3f36, 0x261d: 0x3f3a, + 0x261e: 0x3f3e, 0x261f: 0x3f42, 0x2620: 0x3f46, 0x2621: 0x3f4a, 0x2622: 0x3f4e, 0x2623: 0x2ee5, + 0x2624: 0x3f52, 0x2625: 0x3f57, 0x2626: 0x3f5b, 0x2627: 0x3f5f, 0x2628: 0x2fea, 0x2629: 0x3f5f, + 0x262a: 0x3f63, 0x262b: 0x2eed, 0x262c: 0x3f67, 0x262d: 0x3f6b, 0x262e: 0x3f6f, 0x262f: 0x3f73, + 0x2630: 0x2ef1, 0x2631: 0x2aa5, 0x2632: 0x3f77, 0x2633: 0x3f7b, 0x2634: 0x3f7f, 0x2635: 0x3f83, + 0x2636: 0x3f87, 0x2637: 0x3f8b, 0x2638: 0x3f8f, 0x2639: 0x3f94, 0x263a: 0x3f98, 0x263b: 0x3f9c, + 0x263c: 0x3fa0, 0x263d: 0x3fa4, 0x263e: 0x3fa8, 0x263f: 0x3fad, + // Block 0x99, offset 0x2640 + 0x2640: 0x3fb1, 0x2641: 0x3fb5, 0x2642: 0x3fb9, 0x2643: 0x3fbd, 0x2644: 0x3fc1, 0x2645: 0x3fc5, + 0x2646: 0x3fc9, 0x2647: 0x3fcd, 0x2648: 0x2ef5, 0x2649: 0x3fd1, 0x264a: 0x3fd5, 0x264b: 0x3fda, + 0x264c: 0x3fde, 0x264d: 0x3fe2, 0x264e: 0x3fe6, 0x264f: 0x2efd, 0x2650: 0x3fea, 0x2651: 0x3fee, + 0x2652: 0x3ff2, 0x2653: 0x3ff6, 0x2654: 0x3ffa, 0x2655: 0x3ffe, 0x2656: 0x4002, 0x2657: 0x4006, + 0x2658: 0x2b15, 0x2659: 0x300a, 0x265a: 0x400a, 0x265b: 0x400e, 0x265c: 0x4012, 0x265d: 0x4016, + 0x265e: 0x401b, 0x265f: 0x401f, 0x2660: 0x4023, 0x2661: 0x4027, 0x2662: 0x2f01, 0x2663: 0x402b, + 0x2664: 0x4030, 0x2665: 0x4034, 0x2666: 0x4038, 0x2667: 0x30b5, 0x2668: 0x403c, 0x2669: 0x4040, + 0x266a: 0x4044, 0x266b: 0x4048, 0x266c: 0x404c, 0x266d: 0x4051, 0x266e: 0x4055, 0x266f: 0x4059, + 0x2670: 0x405d, 0x2671: 0x4062, 0x2672: 0x4066, 0x2673: 0x406a, 0x2674: 0x406e, 0x2675: 0x2c25, + 0x2676: 0x4072, 0x2677: 0x4076, 0x2678: 0x407b, 0x2679: 0x4080, 0x267a: 0x4085, 0x267b: 0x4089, + 0x267c: 0x408e, 0x267d: 0x4092, 0x267e: 0x4096, 0x267f: 0x409a, + // Block 0x9a, offset 0x2680 + 0x2680: 0x409e, 0x2681: 0x2f05, 0x2682: 0x2d71, 0x2683: 0x40a2, 0x2684: 0x40a6, 0x2685: 0x40aa, + 0x2686: 0x40ae, 0x2687: 0x40b3, 0x2688: 0x40b7, 0x2689: 0x40bb, 0x268a: 0x40bf, 0x268b: 0x3016, + 0x268c: 0x40c3, 0x268d: 0x40c7, 0x268e: 0x40cc, 0x268f: 0x40d0, 0x2690: 0x40d4, 0x2691: 0x40d9, + 0x2692: 0x40de, 0x2693: 0x40e2, 0x2694: 0x301a, 0x2695: 0x40e6, 0x2696: 0x40ea, 0x2697: 0x40ee, + 0x2698: 0x40f2, 0x2699: 0x40f6, 0x269a: 0x40fa, 0x269b: 0x40fe, 0x269c: 0x4103, 0x269d: 0x4107, + 0x269e: 0x410c, 0x269f: 0x4110, 0x26a0: 0x4115, 0x26a1: 0x3022, 0x26a2: 0x4119, 0x26a3: 0x411d, + 0x26a4: 0x4122, 0x26a5: 0x4126, 0x26a6: 0x412a, 0x26a7: 0x412f, 0x26a8: 0x4134, 0x26a9: 0x4138, + 0x26aa: 0x413c, 0x26ab: 0x4140, 0x26ac: 0x4144, 0x26ad: 0x4144, 0x26ae: 0x4148, 0x26af: 0x414c, + 0x26b0: 0x302a, 0x26b1: 0x4150, 0x26b2: 0x4154, 0x26b3: 0x4158, 0x26b4: 0x415c, 0x26b5: 0x4160, + 0x26b6: 0x4165, 0x26b7: 0x4169, 0x26b8: 0x2bed, 0x26b9: 0x416e, 0x26ba: 0x4173, 0x26bb: 0x4177, + 0x26bc: 0x417c, 0x26bd: 0x4181, 0x26be: 0x4186, 0x26bf: 0x418a, + // Block 0x9b, offset 0x26c0 + 0x26c0: 0x3042, 0x26c1: 0x418e, 0x26c2: 0x4193, 0x26c3: 0x4198, 0x26c4: 0x419d, 0x26c5: 0x41a2, + 0x26c6: 0x41a6, 0x26c7: 0x41a6, 0x26c8: 0x3046, 0x26c9: 0x30bd, 0x26ca: 0x41aa, 0x26cb: 0x41ae, + 0x26cc: 0x41b2, 0x26cd: 0x41b6, 0x26ce: 0x41bb, 0x26cf: 0x2b59, 0x26d0: 0x304e, 0x26d1: 0x41bf, + 0x26d2: 0x41c3, 0x26d3: 0x2f2d, 0x26d4: 0x41c8, 0x26d5: 0x41cd, 0x26d6: 0x2e89, 0x26d7: 0x41d2, + 0x26d8: 0x41d6, 0x26d9: 0x2f39, 0x26da: 0x41da, 0x26db: 0x41de, 0x26dc: 0x41e2, 0x26dd: 0x41e7, + 0x26de: 0x41e7, 0x26df: 0x41ec, 0x26e0: 0x41f0, 0x26e1: 0x41f4, 0x26e2: 0x41f9, 0x26e3: 0x41fd, + 0x26e4: 0x4201, 0x26e5: 0x4205, 0x26e6: 0x420a, 0x26e7: 0x420e, 0x26e8: 0x4212, 0x26e9: 0x4216, + 0x26ea: 0x421a, 0x26eb: 0x421e, 0x26ec: 0x4223, 0x26ed: 0x4227, 0x26ee: 0x422b, 0x26ef: 0x422f, + 0x26f0: 0x4233, 0x26f1: 0x4237, 0x26f2: 0x423b, 0x26f3: 0x4240, 0x26f4: 0x4245, 0x26f5: 0x4249, + 0x26f6: 0x424e, 0x26f7: 0x4252, 0x26f8: 0x4257, 0x26f9: 0x425b, 0x26fa: 0x2f51, 0x26fb: 0x425f, + 0x26fc: 0x4264, 0x26fd: 0x4269, 0x26fe: 0x426d, 0x26ff: 0x4272, + // Block 0x9c, offset 0x2700 + 0x2700: 0x4276, 0x2701: 0x427b, 0x2702: 0x427f, 0x2703: 0x4283, 0x2704: 0x4287, 0x2705: 0x428b, + 0x2706: 0x428f, 0x2707: 0x4293, 0x2708: 0x4298, 0x2709: 0x429d, 0x270a: 0x42a2, 0x270b: 0x3f14, + 0x270c: 0x42a7, 0x270d: 0x42ab, 0x270e: 0x42af, 0x270f: 0x42b3, 0x2710: 0x42b7, 0x2711: 0x42bb, + 0x2712: 0x42bf, 0x2713: 0x42c3, 0x2714: 0x42c7, 0x2715: 0x42cb, 0x2716: 0x42cf, 0x2717: 0x42d3, + 0x2718: 0x2c31, 0x2719: 0x42d8, 0x271a: 0x42dc, 0x271b: 0x42e0, 0x271c: 0x42e4, 0x271d: 0x42e8, + 0x271e: 0x42ec, 0x271f: 0x2f5d, 0x2720: 0x42f0, 0x2721: 0x42f4, 0x2722: 0x42f8, 0x2723: 0x42fc, + 0x2724: 0x4300, 0x2725: 0x4305, 0x2726: 0x430a, 0x2727: 0x430f, 0x2728: 0x4313, 0x2729: 0x4317, + 0x272a: 0x431b, 0x272b: 0x431f, 0x272c: 0x4324, 0x272d: 0x4328, 0x272e: 0x432d, 0x272f: 0x4331, + 0x2730: 0x4335, 0x2731: 0x433a, 0x2732: 0x433f, 0x2733: 0x4343, 0x2734: 0x2b45, 0x2735: 0x4347, + 0x2736: 0x434b, 0x2737: 0x434f, 0x2738: 0x4353, 0x2739: 0x4357, 0x273a: 0x435b, 0x273b: 0x306a, + 0x273c: 0x435f, 0x273d: 0x4363, 0x273e: 0x4367, 0x273f: 0x436b, + // Block 0x9d, offset 0x2740 + 0x2740: 0x436f, 0x2741: 0x4373, 0x2742: 0x4377, 0x2743: 0x437b, 0x2744: 0x1a66, 0x2745: 0x437f, + 0x2746: 0x4384, 0x2747: 0x4388, 0x2748: 0x438c, 0x2749: 0x4390, 0x274a: 0x4394, 0x274b: 0x4398, + 0x274c: 0x439d, 0x274d: 0x43a2, 0x274e: 0x43a6, 0x274f: 0x43aa, 0x2750: 0x307e, 0x2751: 0x3082, + 0x2752: 0x1a82, 0x2753: 0x43ae, 0x2754: 0x43b3, 0x2755: 0x43b7, 0x2756: 0x43bb, 0x2757: 0x43bf, + 0x2758: 0x43c3, 0x2759: 0x43c8, 0x275a: 0x43cd, 0x275b: 0x43d1, 0x275c: 0x43d5, 0x275d: 0x43d9, + 0x275e: 0x43de, 0x275f: 0x3086, 0x2760: 0x43e2, 0x2761: 0x43e7, 0x2762: 0x43ec, 0x2763: 0x43f0, + 0x2764: 0x43f4, 0x2765: 0x43f8, 0x2766: 0x43fd, 0x2767: 0x4401, 0x2768: 0x4405, 0x2769: 0x4409, + 0x276a: 0x440d, 0x276b: 0x4411, 0x276c: 0x4415, 0x276d: 0x4419, 0x276e: 0x441e, 0x276f: 0x4422, + 0x2770: 0x4426, 0x2771: 0x442a, 0x2772: 0x442f, 0x2773: 0x4433, 0x2774: 0x4437, 0x2775: 0x443b, + 0x2776: 0x443f, 0x2777: 0x4444, 0x2778: 0x4449, 0x2779: 0x444d, 0x277a: 0x4451, 0x277b: 0x4455, + 0x277c: 0x445a, 0x277d: 0x445e, 0x277e: 0x309e, 0x277f: 0x309e, + // Block 0x9e, offset 0x2780 + 0x2780: 0x4463, 0x2781: 0x4467, 0x2782: 0x446c, 0x2783: 0x4470, 0x2784: 0x4474, 0x2785: 0x4478, + 0x2786: 0x447c, 0x2787: 0x4480, 0x2788: 0x4484, 0x2789: 0x4488, 0x278a: 0x30a2, 0x278b: 0x448d, + 0x278c: 0x4491, 0x278d: 0x4495, 0x278e: 0x4499, 0x278f: 0x449d, 0x2790: 0x44a1, 0x2791: 0x44a6, + 0x2792: 0x44aa, 0x2793: 0x44af, 0x2794: 0x44b4, 0x2795: 0x1b42, 0x2796: 0x44b9, 0x2797: 0x1b52, + 0x2798: 0x44bd, 0x2799: 0x44c1, 0x279a: 0x44c5, 0x279b: 0x44c9, 0x279c: 0x1b66, 0x279d: 0x44cd, +} + +// nfkcDecompLookup: 960 bytes +// Block 0 is the null block. +var nfkcDecompLookup = [960]uint8{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0x0c2: 0x03, 0x0c3: 0x04, 0x0c4: 0x05, 0x0c5: 0x06, 0x0c6: 0x07, 0x0c7: 0x08, + 0x0c8: 0x09, 0x0ca: 0x0a, 0x0cb: 0x0b, 0x0cd: 0x0c, 0x0ce: 0x0d, 0x0cf: 0x0e, + 0x0d0: 0x0f, 0x0d1: 0x10, 0x0d3: 0x11, 0x0d6: 0x12, + 0x0d8: 0x13, 0x0d9: 0x14, 0x0db: 0x15, + 0x0e0: 0x04, 0x0e1: 0x05, 0x0e2: 0x06, 0x0e3: 0x07, + 0x0ea: 0x08, 0x0ef: 0x09, + 0x0f0: 0x0e, + // Block 0x4, offset 0x100 + 0x124: 0x16, 0x125: 0x17, 0x127: 0x18, + 0x128: 0x19, 0x129: 0x1a, 0x12d: 0x1b, 0x12e: 0x1c, 0x12f: 0x1d, + 0x131: 0x1e, 0x133: 0x1f, 0x135: 0x20, 0x137: 0x21, + 0x138: 0x22, 0x13a: 0x23, 0x13b: 0x24, 0x13c: 0x25, 0x13d: 0x26, 0x13e: 0x27, + // Block 0x5, offset 0x140 + 0x140: 0x28, 0x143: 0x29, + 0x16c: 0x2a, 0x16d: 0x2b, + 0x174: 0x2c, 0x175: 0x2d, 0x176: 0x2e, + 0x178: 0x2f, 0x179: 0x30, 0x17a: 0x31, 0x17b: 0x32, 0x17c: 0x33, 0x17d: 0x34, 0x17e: 0x35, 0x17f: 0x36, + // Block 0x6, offset 0x180 + 0x180: 0x37, 0x181: 0x38, 0x182: 0x39, 0x184: 0x3a, 0x185: 0x3b, 0x186: 0x3c, 0x187: 0x3d, + 0x188: 0x3e, 0x189: 0x3f, 0x18a: 0x40, 0x18b: 0x41, 0x18c: 0x42, + 0x191: 0x43, 0x192: 0x44, 0x193: 0x45, + 0x1a8: 0x46, 0x1a9: 0x47, 0x1ab: 0x48, + 0x1b1: 0x49, 0x1b5: 0x4a, + 0x1ba: 0x4b, 0x1bb: 0x4c, 0x1bc: 0x4d, 0x1bd: 0x4e, 0x1be: 0x4f, 0x1bf: 0x50, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x51, 0x1c1: 0x52, 0x1c2: 0x53, 0x1c3: 0x54, 0x1c4: 0x55, 0x1c5: 0x56, 0x1c6: 0x57, + 0x1c8: 0x58, 0x1c9: 0x59, 0x1ca: 0x5a, 0x1cb: 0x5b, 0x1cc: 0x5c, 0x1cd: 0x5d, 0x1ce: 0x5e, 0x1cf: 0x5f, + // Block 0x8, offset 0x200 + 0x21d: 0x60, + // Block 0x9, offset 0x240 + 0x264: 0x61, 0x265: 0x62, 0x266: 0x63, 0x267: 0x64, + 0x268: 0x65, 0x269: 0x66, 0x26a: 0x67, 0x26b: 0x68, 0x26c: 0x69, 0x26d: 0x6a, 0x26e: 0x6b, 0x26f: 0x6c, + 0x270: 0x6d, 0x271: 0x6e, 0x272: 0x6f, 0x273: 0x70, 0x274: 0x71, 0x275: 0x72, 0x276: 0x73, 0x277: 0x74, + 0x278: 0x75, 0x279: 0x76, 0x27a: 0x77, 0x27b: 0x78, 0x27c: 0x79, 0x27d: 0x7a, 0x27e: 0x7b, 0x27f: 0x7c, + // Block 0xa, offset 0x280 + 0x282: 0x7d, + // Block 0xb, offset 0x2c0 + 0x2c5: 0x7e, 0x2c6: 0x7f, 0x2c7: 0x80, + 0x2d0: 0x81, 0x2d1: 0x82, 0x2d2: 0x83, 0x2d3: 0x84, 0x2d4: 0x85, 0x2d5: 0x86, 0x2d6: 0x87, 0x2d7: 0x88, + 0x2d8: 0x89, 0x2d9: 0x8a, 0x2da: 0x8b, 0x2db: 0x8c, 0x2dc: 0x8d, 0x2dd: 0x8e, 0x2de: 0x8f, 0x2df: 0x90, + // Block 0xc, offset 0x300 + 0x304: 0x91, 0x305: 0x92, 0x306: 0x93, + 0x308: 0x94, 0x309: 0x95, + // Block 0xd, offset 0x340 + 0x360: 0x96, 0x361: 0x97, 0x362: 0x98, 0x363: 0x99, 0x364: 0x9a, 0x365: 0x9b, 0x366: 0x9c, 0x367: 0x9d, + 0x368: 0x9e, + // Block 0xe, offset 0x380 + 0x391: 0x0a, + 0x39d: 0x0b, 0x39f: 0x0c, + 0x3af: 0x0d, +} + +var nfkcDecompTrie = trie{nfkcDecompLookup[:], nfkcDecompValues[:]} + +// recompMap: 7448 bytes (entries only) +var recompMap = map[uint32]uint32{ + 0x00410300: 0x00C0, + 0x00410301: 0x00C1, + 0x00410302: 0x00C2, + 0x00410303: 0x00C3, + 0x00410308: 0x00C4, + 0x0041030A: 0x00C5, + 0x00430327: 0x00C7, + 0x00450300: 0x00C8, + 0x00450301: 0x00C9, + 0x00450302: 0x00CA, + 0x00450308: 0x00CB, + 0x00490300: 0x00CC, + 0x00490301: 0x00CD, + 0x00490302: 0x00CE, + 0x00490308: 0x00CF, + 0x004E0303: 0x00D1, + 0x004F0300: 0x00D2, + 0x004F0301: 0x00D3, + 0x004F0302: 0x00D4, + 0x004F0303: 0x00D5, + 0x004F0308: 0x00D6, + 0x00550300: 0x00D9, + 0x00550301: 0x00DA, + 0x00550302: 0x00DB, + 0x00550308: 0x00DC, + 0x00590301: 0x00DD, + 0x00610300: 0x00E0, + 0x00610301: 0x00E1, + 0x00610302: 0x00E2, + 0x00610303: 0x00E3, + 0x00610308: 0x00E4, + 0x0061030A: 0x00E5, + 0x00630327: 0x00E7, + 0x00650300: 0x00E8, + 0x00650301: 0x00E9, + 0x00650302: 0x00EA, + 0x00650308: 0x00EB, + 0x00690300: 0x00EC, + 0x00690301: 0x00ED, + 0x00690302: 0x00EE, + 0x00690308: 0x00EF, + 0x006E0303: 0x00F1, + 0x006F0300: 0x00F2, + 0x006F0301: 0x00F3, + 0x006F0302: 0x00F4, + 0x006F0303: 0x00F5, + 0x006F0308: 0x00F6, + 0x00750300: 0x00F9, + 0x00750301: 0x00FA, + 0x00750302: 0x00FB, + 0x00750308: 0x00FC, + 0x00790301: 0x00FD, + 0x00790308: 0x00FF, + 0x00410304: 0x0100, + 0x00610304: 0x0101, + 0x00410306: 0x0102, + 0x00610306: 0x0103, + 0x00410328: 0x0104, + 0x00610328: 0x0105, + 0x00430301: 0x0106, + 0x00630301: 0x0107, + 0x00430302: 0x0108, + 0x00630302: 0x0109, + 0x00430307: 0x010A, + 0x00630307: 0x010B, + 0x0043030C: 0x010C, + 0x0063030C: 0x010D, + 0x0044030C: 0x010E, + 0x0064030C: 0x010F, + 0x00450304: 0x0112, + 0x00650304: 0x0113, + 0x00450306: 0x0114, + 0x00650306: 0x0115, + 0x00450307: 0x0116, + 0x00650307: 0x0117, + 0x00450328: 0x0118, + 0x00650328: 0x0119, + 0x0045030C: 0x011A, + 0x0065030C: 0x011B, + 0x00470302: 0x011C, + 0x00670302: 0x011D, + 0x00470306: 0x011E, + 0x00670306: 0x011F, + 0x00470307: 0x0120, + 0x00670307: 0x0121, + 0x00470327: 0x0122, + 0x00670327: 0x0123, + 0x00480302: 0x0124, + 0x00680302: 0x0125, + 0x00490303: 0x0128, + 0x00690303: 0x0129, + 0x00490304: 0x012A, + 0x00690304: 0x012B, + 0x00490306: 0x012C, + 0x00690306: 0x012D, + 0x00490328: 0x012E, + 0x00690328: 0x012F, + 0x00490307: 0x0130, + 0x004A0302: 0x0134, + 0x006A0302: 0x0135, + 0x004B0327: 0x0136, + 0x006B0327: 0x0137, + 0x004C0301: 0x0139, + 0x006C0301: 0x013A, + 0x004C0327: 0x013B, + 0x006C0327: 0x013C, + 0x004C030C: 0x013D, + 0x006C030C: 0x013E, + 0x004E0301: 0x0143, + 0x006E0301: 0x0144, + 0x004E0327: 0x0145, + 0x006E0327: 0x0146, + 0x004E030C: 0x0147, + 0x006E030C: 0x0148, + 0x004F0304: 0x014C, + 0x006F0304: 0x014D, + 0x004F0306: 0x014E, + 0x006F0306: 0x014F, + 0x004F030B: 0x0150, + 0x006F030B: 0x0151, + 0x00520301: 0x0154, + 0x00720301: 0x0155, + 0x00520327: 0x0156, + 0x00720327: 0x0157, + 0x0052030C: 0x0158, + 0x0072030C: 0x0159, + 0x00530301: 0x015A, + 0x00730301: 0x015B, + 0x00530302: 0x015C, + 0x00730302: 0x015D, + 0x00530327: 0x015E, + 0x00730327: 0x015F, + 0x0053030C: 0x0160, + 0x0073030C: 0x0161, + 0x00540327: 0x0162, + 0x00740327: 0x0163, + 0x0054030C: 0x0164, + 0x0074030C: 0x0165, + 0x00550303: 0x0168, + 0x00750303: 0x0169, + 0x00550304: 0x016A, + 0x00750304: 0x016B, + 0x00550306: 0x016C, + 0x00750306: 0x016D, + 0x0055030A: 0x016E, + 0x0075030A: 0x016F, + 0x0055030B: 0x0170, + 0x0075030B: 0x0171, + 0x00550328: 0x0172, + 0x00750328: 0x0173, + 0x00570302: 0x0174, + 0x00770302: 0x0175, + 0x00590302: 0x0176, + 0x00790302: 0x0177, + 0x00590308: 0x0178, + 0x005A0301: 0x0179, + 0x007A0301: 0x017A, + 0x005A0307: 0x017B, + 0x007A0307: 0x017C, + 0x005A030C: 0x017D, + 0x007A030C: 0x017E, + 0x004F031B: 0x01A0, + 0x006F031B: 0x01A1, + 0x0055031B: 0x01AF, + 0x0075031B: 0x01B0, + 0x0041030C: 0x01CD, + 0x0061030C: 0x01CE, + 0x0049030C: 0x01CF, + 0x0069030C: 0x01D0, + 0x004F030C: 0x01D1, + 0x006F030C: 0x01D2, + 0x0055030C: 0x01D3, + 0x0075030C: 0x01D4, + 0x00DC0304: 0x01D5, + 0x00FC0304: 0x01D6, + 0x00DC0301: 0x01D7, + 0x00FC0301: 0x01D8, + 0x00DC030C: 0x01D9, + 0x00FC030C: 0x01DA, + 0x00DC0300: 0x01DB, + 0x00FC0300: 0x01DC, + 0x00C40304: 0x01DE, + 0x00E40304: 0x01DF, + 0x02260304: 0x01E0, + 0x02270304: 0x01E1, + 0x00C60304: 0x01E2, + 0x00E60304: 0x01E3, + 0x0047030C: 0x01E6, + 0x0067030C: 0x01E7, + 0x004B030C: 0x01E8, + 0x006B030C: 0x01E9, + 0x004F0328: 0x01EA, + 0x006F0328: 0x01EB, + 0x01EA0304: 0x01EC, + 0x01EB0304: 0x01ED, + 0x01B7030C: 0x01EE, + 0x0292030C: 0x01EF, + 0x006A030C: 0x01F0, + 0x00470301: 0x01F4, + 0x00670301: 0x01F5, + 0x004E0300: 0x01F8, + 0x006E0300: 0x01F9, + 0x00C50301: 0x01FA, + 0x00E50301: 0x01FB, + 0x00C60301: 0x01FC, + 0x00E60301: 0x01FD, + 0x00D80301: 0x01FE, + 0x00F80301: 0x01FF, + 0x0041030F: 0x0200, + 0x0061030F: 0x0201, + 0x00410311: 0x0202, + 0x00610311: 0x0203, + 0x0045030F: 0x0204, + 0x0065030F: 0x0205, + 0x00450311: 0x0206, + 0x00650311: 0x0207, + 0x0049030F: 0x0208, + 0x0069030F: 0x0209, + 0x00490311: 0x020A, + 0x00690311: 0x020B, + 0x004F030F: 0x020C, + 0x006F030F: 0x020D, + 0x004F0311: 0x020E, + 0x006F0311: 0x020F, + 0x0052030F: 0x0210, + 0x0072030F: 0x0211, + 0x00520311: 0x0212, + 0x00720311: 0x0213, + 0x0055030F: 0x0214, + 0x0075030F: 0x0215, + 0x00550311: 0x0216, + 0x00750311: 0x0217, + 0x00530326: 0x0218, + 0x00730326: 0x0219, + 0x00540326: 0x021A, + 0x00740326: 0x021B, + 0x0048030C: 0x021E, + 0x0068030C: 0x021F, + 0x00410307: 0x0226, + 0x00610307: 0x0227, + 0x00450327: 0x0228, + 0x00650327: 0x0229, + 0x00D60304: 0x022A, + 0x00F60304: 0x022B, + 0x00D50304: 0x022C, + 0x00F50304: 0x022D, + 0x004F0307: 0x022E, + 0x006F0307: 0x022F, + 0x022E0304: 0x0230, + 0x022F0304: 0x0231, + 0x00590304: 0x0232, + 0x00790304: 0x0233, + 0x00A80301: 0x0385, + 0x03910301: 0x0386, + 0x03950301: 0x0388, + 0x03970301: 0x0389, + 0x03990301: 0x038A, + 0x039F0301: 0x038C, + 0x03A50301: 0x038E, + 0x03A90301: 0x038F, + 0x03CA0301: 0x0390, + 0x03990308: 0x03AA, + 0x03A50308: 0x03AB, + 0x03B10301: 0x03AC, + 0x03B50301: 0x03AD, + 0x03B70301: 0x03AE, + 0x03B90301: 0x03AF, + 0x03CB0301: 0x03B0, + 0x03B90308: 0x03CA, + 0x03C50308: 0x03CB, + 0x03BF0301: 0x03CC, + 0x03C50301: 0x03CD, + 0x03C90301: 0x03CE, + 0x03D20301: 0x03D3, + 0x03D20308: 0x03D4, + 0x04150300: 0x0400, + 0x04150308: 0x0401, + 0x04130301: 0x0403, + 0x04060308: 0x0407, + 0x041A0301: 0x040C, + 0x04180300: 0x040D, + 0x04230306: 0x040E, + 0x04180306: 0x0419, + 0x04380306: 0x0439, + 0x04350300: 0x0450, + 0x04350308: 0x0451, + 0x04330301: 0x0453, + 0x04560308: 0x0457, + 0x043A0301: 0x045C, + 0x04380300: 0x045D, + 0x04430306: 0x045E, + 0x0474030F: 0x0476, + 0x0475030F: 0x0477, + 0x04160306: 0x04C1, + 0x04360306: 0x04C2, + 0x04100306: 0x04D0, + 0x04300306: 0x04D1, + 0x04100308: 0x04D2, + 0x04300308: 0x04D3, + 0x04150306: 0x04D6, + 0x04350306: 0x04D7, + 0x04D80308: 0x04DA, + 0x04D90308: 0x04DB, + 0x04160308: 0x04DC, + 0x04360308: 0x04DD, + 0x04170308: 0x04DE, + 0x04370308: 0x04DF, + 0x04180304: 0x04E2, + 0x04380304: 0x04E3, + 0x04180308: 0x04E4, + 0x04380308: 0x04E5, + 0x041E0308: 0x04E6, + 0x043E0308: 0x04E7, + 0x04E80308: 0x04EA, + 0x04E90308: 0x04EB, + 0x042D0308: 0x04EC, + 0x044D0308: 0x04ED, + 0x04230304: 0x04EE, + 0x04430304: 0x04EF, + 0x04230308: 0x04F0, + 0x04430308: 0x04F1, + 0x0423030B: 0x04F2, + 0x0443030B: 0x04F3, + 0x04270308: 0x04F4, + 0x04470308: 0x04F5, + 0x042B0308: 0x04F8, + 0x044B0308: 0x04F9, + 0x06270653: 0x0622, + 0x06270654: 0x0623, + 0x06480654: 0x0624, + 0x06270655: 0x0625, + 0x064A0654: 0x0626, + 0x06D50654: 0x06C0, + 0x06C10654: 0x06C2, + 0x06D20654: 0x06D3, + 0x0928093C: 0x0929, + 0x0930093C: 0x0931, + 0x0933093C: 0x0934, + 0x09C709BE: 0x09CB, + 0x09C709D7: 0x09CC, + 0x0B470B56: 0x0B48, + 0x0B470B3E: 0x0B4B, + 0x0B470B57: 0x0B4C, + 0x0B920BD7: 0x0B94, + 0x0BC60BBE: 0x0BCA, + 0x0BC70BBE: 0x0BCB, + 0x0BC60BD7: 0x0BCC, + 0x0C460C56: 0x0C48, + 0x0CBF0CD5: 0x0CC0, + 0x0CC60CD5: 0x0CC7, + 0x0CC60CD6: 0x0CC8, + 0x0CC60CC2: 0x0CCA, + 0x0CCA0CD5: 0x0CCB, + 0x0D460D3E: 0x0D4A, + 0x0D470D3E: 0x0D4B, + 0x0D460D57: 0x0D4C, + 0x0DD90DCA: 0x0DDA, + 0x0DD90DCF: 0x0DDC, + 0x0DDC0DCA: 0x0DDD, + 0x0DD90DDF: 0x0DDE, + 0x1025102E: 0x1026, + 0x1B051B35: 0x1B06, + 0x1B071B35: 0x1B08, + 0x1B091B35: 0x1B0A, + 0x1B0B1B35: 0x1B0C, + 0x1B0D1B35: 0x1B0E, + 0x1B111B35: 0x1B12, + 0x1B3A1B35: 0x1B3B, + 0x1B3C1B35: 0x1B3D, + 0x1B3E1B35: 0x1B40, + 0x1B3F1B35: 0x1B41, + 0x1B421B35: 0x1B43, + 0x00410325: 0x1E00, + 0x00610325: 0x1E01, + 0x00420307: 0x1E02, + 0x00620307: 0x1E03, + 0x00420323: 0x1E04, + 0x00620323: 0x1E05, + 0x00420331: 0x1E06, + 0x00620331: 0x1E07, + 0x00C70301: 0x1E08, + 0x00E70301: 0x1E09, + 0x00440307: 0x1E0A, + 0x00640307: 0x1E0B, + 0x00440323: 0x1E0C, + 0x00640323: 0x1E0D, + 0x00440331: 0x1E0E, + 0x00640331: 0x1E0F, + 0x00440327: 0x1E10, + 0x00640327: 0x1E11, + 0x0044032D: 0x1E12, + 0x0064032D: 0x1E13, + 0x01120300: 0x1E14, + 0x01130300: 0x1E15, + 0x01120301: 0x1E16, + 0x01130301: 0x1E17, + 0x0045032D: 0x1E18, + 0x0065032D: 0x1E19, + 0x00450330: 0x1E1A, + 0x00650330: 0x1E1B, + 0x02280306: 0x1E1C, + 0x02290306: 0x1E1D, + 0x00460307: 0x1E1E, + 0x00660307: 0x1E1F, + 0x00470304: 0x1E20, + 0x00670304: 0x1E21, + 0x00480307: 0x1E22, + 0x00680307: 0x1E23, + 0x00480323: 0x1E24, + 0x00680323: 0x1E25, + 0x00480308: 0x1E26, + 0x00680308: 0x1E27, + 0x00480327: 0x1E28, + 0x00680327: 0x1E29, + 0x0048032E: 0x1E2A, + 0x0068032E: 0x1E2B, + 0x00490330: 0x1E2C, + 0x00690330: 0x1E2D, + 0x00CF0301: 0x1E2E, + 0x00EF0301: 0x1E2F, + 0x004B0301: 0x1E30, + 0x006B0301: 0x1E31, + 0x004B0323: 0x1E32, + 0x006B0323: 0x1E33, + 0x004B0331: 0x1E34, + 0x006B0331: 0x1E35, + 0x004C0323: 0x1E36, + 0x006C0323: 0x1E37, + 0x1E360304: 0x1E38, + 0x1E370304: 0x1E39, + 0x004C0331: 0x1E3A, + 0x006C0331: 0x1E3B, + 0x004C032D: 0x1E3C, + 0x006C032D: 0x1E3D, + 0x004D0301: 0x1E3E, + 0x006D0301: 0x1E3F, + 0x004D0307: 0x1E40, + 0x006D0307: 0x1E41, + 0x004D0323: 0x1E42, + 0x006D0323: 0x1E43, + 0x004E0307: 0x1E44, + 0x006E0307: 0x1E45, + 0x004E0323: 0x1E46, + 0x006E0323: 0x1E47, + 0x004E0331: 0x1E48, + 0x006E0331: 0x1E49, + 0x004E032D: 0x1E4A, + 0x006E032D: 0x1E4B, + 0x00D50301: 0x1E4C, + 0x00F50301: 0x1E4D, + 0x00D50308: 0x1E4E, + 0x00F50308: 0x1E4F, + 0x014C0300: 0x1E50, + 0x014D0300: 0x1E51, + 0x014C0301: 0x1E52, + 0x014D0301: 0x1E53, + 0x00500301: 0x1E54, + 0x00700301: 0x1E55, + 0x00500307: 0x1E56, + 0x00700307: 0x1E57, + 0x00520307: 0x1E58, + 0x00720307: 0x1E59, + 0x00520323: 0x1E5A, + 0x00720323: 0x1E5B, + 0x1E5A0304: 0x1E5C, + 0x1E5B0304: 0x1E5D, + 0x00520331: 0x1E5E, + 0x00720331: 0x1E5F, + 0x00530307: 0x1E60, + 0x00730307: 0x1E61, + 0x00530323: 0x1E62, + 0x00730323: 0x1E63, + 0x015A0307: 0x1E64, + 0x015B0307: 0x1E65, + 0x01600307: 0x1E66, + 0x01610307: 0x1E67, + 0x1E620307: 0x1E68, + 0x1E630307: 0x1E69, + 0x00540307: 0x1E6A, + 0x00740307: 0x1E6B, + 0x00540323: 0x1E6C, + 0x00740323: 0x1E6D, + 0x00540331: 0x1E6E, + 0x00740331: 0x1E6F, + 0x0054032D: 0x1E70, + 0x0074032D: 0x1E71, + 0x00550324: 0x1E72, + 0x00750324: 0x1E73, + 0x00550330: 0x1E74, + 0x00750330: 0x1E75, + 0x0055032D: 0x1E76, + 0x0075032D: 0x1E77, + 0x01680301: 0x1E78, + 0x01690301: 0x1E79, + 0x016A0308: 0x1E7A, + 0x016B0308: 0x1E7B, + 0x00560303: 0x1E7C, + 0x00760303: 0x1E7D, + 0x00560323: 0x1E7E, + 0x00760323: 0x1E7F, + 0x00570300: 0x1E80, + 0x00770300: 0x1E81, + 0x00570301: 0x1E82, + 0x00770301: 0x1E83, + 0x00570308: 0x1E84, + 0x00770308: 0x1E85, + 0x00570307: 0x1E86, + 0x00770307: 0x1E87, + 0x00570323: 0x1E88, + 0x00770323: 0x1E89, + 0x00580307: 0x1E8A, + 0x00780307: 0x1E8B, + 0x00580308: 0x1E8C, + 0x00780308: 0x1E8D, + 0x00590307: 0x1E8E, + 0x00790307: 0x1E8F, + 0x005A0302: 0x1E90, + 0x007A0302: 0x1E91, + 0x005A0323: 0x1E92, + 0x007A0323: 0x1E93, + 0x005A0331: 0x1E94, + 0x007A0331: 0x1E95, + 0x00680331: 0x1E96, + 0x00740308: 0x1E97, + 0x0077030A: 0x1E98, + 0x0079030A: 0x1E99, + 0x017F0307: 0x1E9B, + 0x00410323: 0x1EA0, + 0x00610323: 0x1EA1, + 0x00410309: 0x1EA2, + 0x00610309: 0x1EA3, + 0x00C20301: 0x1EA4, + 0x00E20301: 0x1EA5, + 0x00C20300: 0x1EA6, + 0x00E20300: 0x1EA7, + 0x00C20309: 0x1EA8, + 0x00E20309: 0x1EA9, + 0x00C20303: 0x1EAA, + 0x00E20303: 0x1EAB, + 0x1EA00302: 0x1EAC, + 0x1EA10302: 0x1EAD, + 0x01020301: 0x1EAE, + 0x01030301: 0x1EAF, + 0x01020300: 0x1EB0, + 0x01030300: 0x1EB1, + 0x01020309: 0x1EB2, + 0x01030309: 0x1EB3, + 0x01020303: 0x1EB4, + 0x01030303: 0x1EB5, + 0x1EA00306: 0x1EB6, + 0x1EA10306: 0x1EB7, + 0x00450323: 0x1EB8, + 0x00650323: 0x1EB9, + 0x00450309: 0x1EBA, + 0x00650309: 0x1EBB, + 0x00450303: 0x1EBC, + 0x00650303: 0x1EBD, + 0x00CA0301: 0x1EBE, + 0x00EA0301: 0x1EBF, + 0x00CA0300: 0x1EC0, + 0x00EA0300: 0x1EC1, + 0x00CA0309: 0x1EC2, + 0x00EA0309: 0x1EC3, + 0x00CA0303: 0x1EC4, + 0x00EA0303: 0x1EC5, + 0x1EB80302: 0x1EC6, + 0x1EB90302: 0x1EC7, + 0x00490309: 0x1EC8, + 0x00690309: 0x1EC9, + 0x00490323: 0x1ECA, + 0x00690323: 0x1ECB, + 0x004F0323: 0x1ECC, + 0x006F0323: 0x1ECD, + 0x004F0309: 0x1ECE, + 0x006F0309: 0x1ECF, + 0x00D40301: 0x1ED0, + 0x00F40301: 0x1ED1, + 0x00D40300: 0x1ED2, + 0x00F40300: 0x1ED3, + 0x00D40309: 0x1ED4, + 0x00F40309: 0x1ED5, + 0x00D40303: 0x1ED6, + 0x00F40303: 0x1ED7, + 0x1ECC0302: 0x1ED8, + 0x1ECD0302: 0x1ED9, + 0x01A00301: 0x1EDA, + 0x01A10301: 0x1EDB, + 0x01A00300: 0x1EDC, + 0x01A10300: 0x1EDD, + 0x01A00309: 0x1EDE, + 0x01A10309: 0x1EDF, + 0x01A00303: 0x1EE0, + 0x01A10303: 0x1EE1, + 0x01A00323: 0x1EE2, + 0x01A10323: 0x1EE3, + 0x00550323: 0x1EE4, + 0x00750323: 0x1EE5, + 0x00550309: 0x1EE6, + 0x00750309: 0x1EE7, + 0x01AF0301: 0x1EE8, + 0x01B00301: 0x1EE9, + 0x01AF0300: 0x1EEA, + 0x01B00300: 0x1EEB, + 0x01AF0309: 0x1EEC, + 0x01B00309: 0x1EED, + 0x01AF0303: 0x1EEE, + 0x01B00303: 0x1EEF, + 0x01AF0323: 0x1EF0, + 0x01B00323: 0x1EF1, + 0x00590300: 0x1EF2, + 0x00790300: 0x1EF3, + 0x00590323: 0x1EF4, + 0x00790323: 0x1EF5, + 0x00590309: 0x1EF6, + 0x00790309: 0x1EF7, + 0x00590303: 0x1EF8, + 0x00790303: 0x1EF9, + 0x03B10313: 0x1F00, + 0x03B10314: 0x1F01, + 0x1F000300: 0x1F02, + 0x1F010300: 0x1F03, + 0x1F000301: 0x1F04, + 0x1F010301: 0x1F05, + 0x1F000342: 0x1F06, + 0x1F010342: 0x1F07, + 0x03910313: 0x1F08, + 0x03910314: 0x1F09, + 0x1F080300: 0x1F0A, + 0x1F090300: 0x1F0B, + 0x1F080301: 0x1F0C, + 0x1F090301: 0x1F0D, + 0x1F080342: 0x1F0E, + 0x1F090342: 0x1F0F, + 0x03B50313: 0x1F10, + 0x03B50314: 0x1F11, + 0x1F100300: 0x1F12, + 0x1F110300: 0x1F13, + 0x1F100301: 0x1F14, + 0x1F110301: 0x1F15, + 0x03950313: 0x1F18, + 0x03950314: 0x1F19, + 0x1F180300: 0x1F1A, + 0x1F190300: 0x1F1B, + 0x1F180301: 0x1F1C, + 0x1F190301: 0x1F1D, + 0x03B70313: 0x1F20, + 0x03B70314: 0x1F21, + 0x1F200300: 0x1F22, + 0x1F210300: 0x1F23, + 0x1F200301: 0x1F24, + 0x1F210301: 0x1F25, + 0x1F200342: 0x1F26, + 0x1F210342: 0x1F27, + 0x03970313: 0x1F28, + 0x03970314: 0x1F29, + 0x1F280300: 0x1F2A, + 0x1F290300: 0x1F2B, + 0x1F280301: 0x1F2C, + 0x1F290301: 0x1F2D, + 0x1F280342: 0x1F2E, + 0x1F290342: 0x1F2F, + 0x03B90313: 0x1F30, + 0x03B90314: 0x1F31, + 0x1F300300: 0x1F32, + 0x1F310300: 0x1F33, + 0x1F300301: 0x1F34, + 0x1F310301: 0x1F35, + 0x1F300342: 0x1F36, + 0x1F310342: 0x1F37, + 0x03990313: 0x1F38, + 0x03990314: 0x1F39, + 0x1F380300: 0x1F3A, + 0x1F390300: 0x1F3B, + 0x1F380301: 0x1F3C, + 0x1F390301: 0x1F3D, + 0x1F380342: 0x1F3E, + 0x1F390342: 0x1F3F, + 0x03BF0313: 0x1F40, + 0x03BF0314: 0x1F41, + 0x1F400300: 0x1F42, + 0x1F410300: 0x1F43, + 0x1F400301: 0x1F44, + 0x1F410301: 0x1F45, + 0x039F0313: 0x1F48, + 0x039F0314: 0x1F49, + 0x1F480300: 0x1F4A, + 0x1F490300: 0x1F4B, + 0x1F480301: 0x1F4C, + 0x1F490301: 0x1F4D, + 0x03C50313: 0x1F50, + 0x03C50314: 0x1F51, + 0x1F500300: 0x1F52, + 0x1F510300: 0x1F53, + 0x1F500301: 0x1F54, + 0x1F510301: 0x1F55, + 0x1F500342: 0x1F56, + 0x1F510342: 0x1F57, + 0x03A50314: 0x1F59, + 0x1F590300: 0x1F5B, + 0x1F590301: 0x1F5D, + 0x1F590342: 0x1F5F, + 0x03C90313: 0x1F60, + 0x03C90314: 0x1F61, + 0x1F600300: 0x1F62, + 0x1F610300: 0x1F63, + 0x1F600301: 0x1F64, + 0x1F610301: 0x1F65, + 0x1F600342: 0x1F66, + 0x1F610342: 0x1F67, + 0x03A90313: 0x1F68, + 0x03A90314: 0x1F69, + 0x1F680300: 0x1F6A, + 0x1F690300: 0x1F6B, + 0x1F680301: 0x1F6C, + 0x1F690301: 0x1F6D, + 0x1F680342: 0x1F6E, + 0x1F690342: 0x1F6F, + 0x03B10300: 0x1F70, + 0x03B50300: 0x1F72, + 0x03B70300: 0x1F74, + 0x03B90300: 0x1F76, + 0x03BF0300: 0x1F78, + 0x03C50300: 0x1F7A, + 0x03C90300: 0x1F7C, + 0x1F000345: 0x1F80, + 0x1F010345: 0x1F81, + 0x1F020345: 0x1F82, + 0x1F030345: 0x1F83, + 0x1F040345: 0x1F84, + 0x1F050345: 0x1F85, + 0x1F060345: 0x1F86, + 0x1F070345: 0x1F87, + 0x1F080345: 0x1F88, + 0x1F090345: 0x1F89, + 0x1F0A0345: 0x1F8A, + 0x1F0B0345: 0x1F8B, + 0x1F0C0345: 0x1F8C, + 0x1F0D0345: 0x1F8D, + 0x1F0E0345: 0x1F8E, + 0x1F0F0345: 0x1F8F, + 0x1F200345: 0x1F90, + 0x1F210345: 0x1F91, + 0x1F220345: 0x1F92, + 0x1F230345: 0x1F93, + 0x1F240345: 0x1F94, + 0x1F250345: 0x1F95, + 0x1F260345: 0x1F96, + 0x1F270345: 0x1F97, + 0x1F280345: 0x1F98, + 0x1F290345: 0x1F99, + 0x1F2A0345: 0x1F9A, + 0x1F2B0345: 0x1F9B, + 0x1F2C0345: 0x1F9C, + 0x1F2D0345: 0x1F9D, + 0x1F2E0345: 0x1F9E, + 0x1F2F0345: 0x1F9F, + 0x1F600345: 0x1FA0, + 0x1F610345: 0x1FA1, + 0x1F620345: 0x1FA2, + 0x1F630345: 0x1FA3, + 0x1F640345: 0x1FA4, + 0x1F650345: 0x1FA5, + 0x1F660345: 0x1FA6, + 0x1F670345: 0x1FA7, + 0x1F680345: 0x1FA8, + 0x1F690345: 0x1FA9, + 0x1F6A0345: 0x1FAA, + 0x1F6B0345: 0x1FAB, + 0x1F6C0345: 0x1FAC, + 0x1F6D0345: 0x1FAD, + 0x1F6E0345: 0x1FAE, + 0x1F6F0345: 0x1FAF, + 0x03B10306: 0x1FB0, + 0x03B10304: 0x1FB1, + 0x1F700345: 0x1FB2, + 0x03B10345: 0x1FB3, + 0x03AC0345: 0x1FB4, + 0x03B10342: 0x1FB6, + 0x1FB60345: 0x1FB7, + 0x03910306: 0x1FB8, + 0x03910304: 0x1FB9, + 0x03910300: 0x1FBA, + 0x03910345: 0x1FBC, + 0x00A80342: 0x1FC1, + 0x1F740345: 0x1FC2, + 0x03B70345: 0x1FC3, + 0x03AE0345: 0x1FC4, + 0x03B70342: 0x1FC6, + 0x1FC60345: 0x1FC7, + 0x03950300: 0x1FC8, + 0x03970300: 0x1FCA, + 0x03970345: 0x1FCC, + 0x1FBF0300: 0x1FCD, + 0x1FBF0301: 0x1FCE, + 0x1FBF0342: 0x1FCF, + 0x03B90306: 0x1FD0, + 0x03B90304: 0x1FD1, + 0x03CA0300: 0x1FD2, + 0x03B90342: 0x1FD6, + 0x03CA0342: 0x1FD7, + 0x03990306: 0x1FD8, + 0x03990304: 0x1FD9, + 0x03990300: 0x1FDA, + 0x1FFE0300: 0x1FDD, + 0x1FFE0301: 0x1FDE, + 0x1FFE0342: 0x1FDF, + 0x03C50306: 0x1FE0, + 0x03C50304: 0x1FE1, + 0x03CB0300: 0x1FE2, + 0x03C10313: 0x1FE4, + 0x03C10314: 0x1FE5, + 0x03C50342: 0x1FE6, + 0x03CB0342: 0x1FE7, + 0x03A50306: 0x1FE8, + 0x03A50304: 0x1FE9, + 0x03A50300: 0x1FEA, + 0x03A10314: 0x1FEC, + 0x00A80300: 0x1FED, + 0x1F7C0345: 0x1FF2, + 0x03C90345: 0x1FF3, + 0x03CE0345: 0x1FF4, + 0x03C90342: 0x1FF6, + 0x1FF60345: 0x1FF7, + 0x039F0300: 0x1FF8, + 0x03A90300: 0x1FFA, + 0x03A90345: 0x1FFC, + 0x21900338: 0x219A, + 0x21920338: 0x219B, + 0x21940338: 0x21AE, + 0x21D00338: 0x21CD, + 0x21D40338: 0x21CE, + 0x21D20338: 0x21CF, + 0x22030338: 0x2204, + 0x22080338: 0x2209, + 0x220B0338: 0x220C, + 0x22230338: 0x2224, + 0x22250338: 0x2226, + 0x223C0338: 0x2241, + 0x22430338: 0x2244, + 0x22450338: 0x2247, + 0x22480338: 0x2249, + 0x003D0338: 0x2260, + 0x22610338: 0x2262, + 0x224D0338: 0x226D, + 0x003C0338: 0x226E, + 0x003E0338: 0x226F, + 0x22640338: 0x2270, + 0x22650338: 0x2271, + 0x22720338: 0x2274, + 0x22730338: 0x2275, + 0x22760338: 0x2278, + 0x22770338: 0x2279, + 0x227A0338: 0x2280, + 0x227B0338: 0x2281, + 0x22820338: 0x2284, + 0x22830338: 0x2285, + 0x22860338: 0x2288, + 0x22870338: 0x2289, + 0x22A20338: 0x22AC, + 0x22A80338: 0x22AD, + 0x22A90338: 0x22AE, + 0x22AB0338: 0x22AF, + 0x227C0338: 0x22E0, + 0x227D0338: 0x22E1, + 0x22910338: 0x22E2, + 0x22920338: 0x22E3, + 0x22B20338: 0x22EA, + 0x22B30338: 0x22EB, + 0x22B40338: 0x22EC, + 0x22B50338: 0x22ED, + 0x304B3099: 0x304C, + 0x304D3099: 0x304E, + 0x304F3099: 0x3050, + 0x30513099: 0x3052, + 0x30533099: 0x3054, + 0x30553099: 0x3056, + 0x30573099: 0x3058, + 0x30593099: 0x305A, + 0x305B3099: 0x305C, + 0x305D3099: 0x305E, + 0x305F3099: 0x3060, + 0x30613099: 0x3062, + 0x30643099: 0x3065, + 0x30663099: 0x3067, + 0x30683099: 0x3069, + 0x306F3099: 0x3070, + 0x306F309A: 0x3071, + 0x30723099: 0x3073, + 0x3072309A: 0x3074, + 0x30753099: 0x3076, + 0x3075309A: 0x3077, + 0x30783099: 0x3079, + 0x3078309A: 0x307A, + 0x307B3099: 0x307C, + 0x307B309A: 0x307D, + 0x30463099: 0x3094, + 0x309D3099: 0x309E, + 0x30AB3099: 0x30AC, + 0x30AD3099: 0x30AE, + 0x30AF3099: 0x30B0, + 0x30B13099: 0x30B2, + 0x30B33099: 0x30B4, + 0x30B53099: 0x30B6, + 0x30B73099: 0x30B8, + 0x30B93099: 0x30BA, + 0x30BB3099: 0x30BC, + 0x30BD3099: 0x30BE, + 0x30BF3099: 0x30C0, + 0x30C13099: 0x30C2, + 0x30C43099: 0x30C5, + 0x30C63099: 0x30C7, + 0x30C83099: 0x30C9, + 0x30CF3099: 0x30D0, + 0x30CF309A: 0x30D1, + 0x30D23099: 0x30D3, + 0x30D2309A: 0x30D4, + 0x30D53099: 0x30D6, + 0x30D5309A: 0x30D7, + 0x30D83099: 0x30D9, + 0x30D8309A: 0x30DA, + 0x30DB3099: 0x30DC, + 0x30DB309A: 0x30DD, + 0x30A63099: 0x30F4, + 0x30EF3099: 0x30F7, + 0x30F03099: 0x30F8, + 0x30F13099: 0x30F9, + 0x30F23099: 0x30FA, + 0x30FD3099: 0x30FE, + 0x109910BA: 0x1109A, + 0x109B10BA: 0x1109C, + 0x10A510BA: 0x110AB, +} + +// charInfoValues: 10944 entries, 21888 bytes +// Block 2 is the null block. +var charInfoValues = [10944]uint16{ + // Block 0x0, offset 0x0 + 0x003c: 0x8800, 0x003d: 0x8800, 0x003e: 0x8800, + // Block 0x1, offset 0x40 + 0x0041: 0x8800, 0x0042: 0x8800, 0x0043: 0x8800, 0x0044: 0x8800, 0x0045: 0x8800, + 0x0046: 0x8800, 0x0047: 0x8800, 0x0048: 0x8800, 0x0049: 0x8800, 0x004a: 0x8800, 0x004b: 0x8800, + 0x004c: 0x8800, 0x004d: 0x8800, 0x004e: 0x8800, 0x004f: 0x8800, 0x0050: 0x8800, + 0x0052: 0x8800, 0x0053: 0x8800, 0x0054: 0x8800, 0x0055: 0x8800, 0x0056: 0x8800, 0x0057: 0x8800, + 0x0058: 0x8800, 0x0059: 0x8800, 0x005a: 0x8800, + 0x0061: 0x8800, 0x0062: 0x8800, 0x0063: 0x8800, + 0x0064: 0x8800, 0x0065: 0x8800, 0x0066: 0x8800, 0x0067: 0x8800, 0x0068: 0x8800, 0x0069: 0x8800, + 0x006a: 0x8800, 0x006b: 0x8800, 0x006c: 0x8800, 0x006d: 0x8800, 0x006e: 0x8800, 0x006f: 0x8800, + 0x0070: 0x8800, 0x0072: 0x8800, 0x0073: 0x8800, 0x0074: 0x8800, 0x0075: 0x8800, + 0x0076: 0x8800, 0x0077: 0x8800, 0x0078: 0x8800, 0x0079: 0x8800, 0x007a: 0x8800, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0x00e0: 0x3000, + 0x00e8: 0x3800, + 0x00ea: 0x3000, 0x00ef: 0x3000, + 0x00f2: 0x3000, 0x00f3: 0x3000, 0x00f4: 0x3000, 0x00f5: 0x3000, + 0x00f8: 0x3000, 0x00f9: 0x3000, 0x00fa: 0x3000, + 0x00fc: 0x3000, 0x00fd: 0x3000, 0x00fe: 0x3000, + // Block 0x4, offset 0x100 + 0x0100: 0x1100, 0x0101: 0x1100, 0x0102: 0x9900, 0x0103: 0x1100, 0x0104: 0x9900, 0x0105: 0x9900, + 0x0106: 0x8800, 0x0107: 0x9900, 0x0108: 0x1100, 0x0109: 0x1100, 0x010a: 0x9900, 0x010b: 0x1100, + 0x010c: 0x1100, 0x010d: 0x1100, 0x010e: 0x1100, 0x010f: 0x9900, 0x0111: 0x1100, + 0x0112: 0x1100, 0x0113: 0x1100, 0x0114: 0x9900, 0x0115: 0x9900, 0x0116: 0x9900, + 0x0118: 0x8800, 0x0119: 0x1100, 0x011a: 0x1100, 0x011b: 0x1100, 0x011c: 0x9900, 0x011d: 0x1100, + 0x0120: 0x1100, 0x0121: 0x1100, 0x0122: 0x9900, 0x0123: 0x1100, + 0x0124: 0x9900, 0x0125: 0x9900, 0x0126: 0x8800, 0x0127: 0x9900, 0x0128: 0x1100, 0x0129: 0x1100, + 0x012a: 0x9900, 0x012b: 0x1100, 0x012c: 0x1100, 0x012d: 0x1100, 0x012e: 0x1100, 0x012f: 0x9900, + 0x0131: 0x1100, 0x0132: 0x1100, 0x0133: 0x1100, 0x0134: 0x9900, 0x0135: 0x9900, + 0x0136: 0x9900, 0x0138: 0x8800, 0x0139: 0x1100, 0x013a: 0x1100, 0x013b: 0x1100, + 0x013c: 0x9900, 0x013d: 0x1100, 0x013f: 0x1100, + // Block 0x5, offset 0x140 + 0x0140: 0x1100, 0x0141: 0x1100, 0x0142: 0x9900, 0x0143: 0x9900, 0x0144: 0x1100, 0x0145: 0x1100, + 0x0146: 0x1100, 0x0147: 0x1100, 0x0148: 0x1100, 0x0149: 0x1100, 0x014a: 0x1100, 0x014b: 0x1100, + 0x014c: 0x1100, 0x014d: 0x1100, 0x014e: 0x1100, 0x014f: 0x1100, + 0x0152: 0x9900, 0x0153: 0x9900, 0x0154: 0x1100, 0x0155: 0x1100, 0x0156: 0x1100, 0x0157: 0x1100, + 0x0158: 0x1100, 0x0159: 0x1100, 0x015a: 0x1100, 0x015b: 0x1100, 0x015c: 0x1100, 0x015d: 0x1100, + 0x015e: 0x1100, 0x015f: 0x1100, 0x0160: 0x1100, 0x0161: 0x1100, 0x0162: 0x1100, 0x0163: 0x1100, + 0x0164: 0x1100, 0x0165: 0x1100, 0x0168: 0x1100, 0x0169: 0x1100, + 0x016a: 0x1100, 0x016b: 0x1100, 0x016c: 0x1100, 0x016d: 0x1100, 0x016e: 0x1100, 0x016f: 0x1100, + 0x0170: 0x1100, 0x0172: 0x3000, 0x0173: 0x3000, 0x0174: 0x1100, 0x0175: 0x1100, + 0x0176: 0x1100, 0x0177: 0x1100, 0x0179: 0x1100, 0x017a: 0x1100, 0x017b: 0x1100, + 0x017c: 0x1100, 0x017d: 0x1100, 0x017e: 0x1100, 0x017f: 0x3000, + // Block 0x6, offset 0x180 + 0x0180: 0x3000, 0x0183: 0x1100, 0x0184: 0x1100, 0x0185: 0x1100, + 0x0186: 0x1100, 0x0187: 0x1100, 0x0188: 0x1100, 0x0189: 0x3000, + 0x018c: 0x9900, 0x018d: 0x9900, 0x018e: 0x1100, 0x018f: 0x1100, 0x0190: 0x1100, 0x0191: 0x1100, + 0x0194: 0x1100, 0x0195: 0x1100, 0x0196: 0x1100, 0x0197: 0x1100, + 0x0198: 0x1100, 0x0199: 0x1100, 0x019a: 0x9900, 0x019b: 0x9900, 0x019c: 0x1100, 0x019d: 0x1100, + 0x019e: 0x1100, 0x019f: 0x1100, 0x01a0: 0x9900, 0x01a1: 0x9900, 0x01a2: 0x1100, 0x01a3: 0x1100, + 0x01a4: 0x1100, 0x01a5: 0x1100, 0x01a8: 0x9900, 0x01a9: 0x9900, + 0x01aa: 0x9900, 0x01ab: 0x9900, 0x01ac: 0x1100, 0x01ad: 0x1100, 0x01ae: 0x1100, 0x01af: 0x1100, + 0x01b0: 0x1100, 0x01b1: 0x1100, 0x01b2: 0x1100, 0x01b3: 0x1100, 0x01b4: 0x1100, 0x01b5: 0x1100, + 0x01b6: 0x1100, 0x01b7: 0x1100, 0x01b8: 0x1100, 0x01b9: 0x1100, 0x01ba: 0x1100, 0x01bb: 0x1100, + 0x01bc: 0x1100, 0x01bd: 0x1100, 0x01be: 0x1100, 0x01bf: 0x3800, + // Block 0x7, offset 0x1c0 + 0x01e0: 0x9900, 0x01e1: 0x9900, + 0x01ef: 0x9900, + 0x01f0: 0x9900, + 0x01f7: 0x8800, + // Block 0x8, offset 0x200 + 0x0204: 0x3000, 0x0205: 0x3000, + 0x0206: 0x3000, 0x0207: 0x3000, 0x0208: 0x3000, 0x0209: 0x3000, 0x020a: 0x3000, 0x020b: 0x3000, + 0x020c: 0x3000, 0x020d: 0x1100, 0x020e: 0x1100, 0x020f: 0x1100, 0x0210: 0x1100, 0x0211: 0x1100, + 0x0212: 0x1100, 0x0213: 0x1100, 0x0214: 0x1100, 0x0215: 0x1100, 0x0216: 0x1100, 0x0217: 0x1100, + 0x0218: 0x1100, 0x0219: 0x1100, 0x021a: 0x1100, 0x021b: 0x1100, 0x021c: 0x1100, + 0x021e: 0x1100, 0x021f: 0x1100, 0x0220: 0x1100, 0x0221: 0x1100, 0x0222: 0x1100, 0x0223: 0x1100, + 0x0226: 0x1100, 0x0227: 0x1100, 0x0228: 0x1100, 0x0229: 0x1100, + 0x022a: 0x9900, 0x022b: 0x9900, 0x022c: 0x1100, 0x022d: 0x1100, 0x022e: 0x1100, 0x022f: 0x1100, + 0x0230: 0x1100, 0x0231: 0x3000, 0x0232: 0x3000, 0x0233: 0x3000, 0x0234: 0x1100, 0x0235: 0x1100, + 0x0238: 0x1100, 0x0239: 0x1100, 0x023a: 0x1100, 0x023b: 0x1100, + 0x023c: 0x1100, 0x023d: 0x1100, 0x023e: 0x1100, 0x023f: 0x1100, + // Block 0x9, offset 0x240 + 0x0240: 0x1100, 0x0241: 0x1100, 0x0242: 0x1100, 0x0243: 0x1100, 0x0244: 0x1100, 0x0245: 0x1100, + 0x0246: 0x1100, 0x0247: 0x1100, 0x0248: 0x1100, 0x0249: 0x1100, 0x024a: 0x1100, 0x024b: 0x1100, + 0x024c: 0x1100, 0x024d: 0x1100, 0x024e: 0x1100, 0x024f: 0x1100, 0x0250: 0x1100, 0x0251: 0x1100, + 0x0252: 0x1100, 0x0253: 0x1100, 0x0254: 0x1100, 0x0255: 0x1100, 0x0256: 0x1100, 0x0257: 0x1100, + 0x0258: 0x1100, 0x0259: 0x1100, 0x025a: 0x1100, 0x025b: 0x1100, + 0x025e: 0x1100, 0x025f: 0x1100, + 0x0266: 0x9900, 0x0267: 0x9900, 0x0268: 0x9900, 0x0269: 0x9900, + 0x026a: 0x1100, 0x026b: 0x1100, 0x026c: 0x1100, 0x026d: 0x1100, 0x026e: 0x9900, 0x026f: 0x9900, + 0x0270: 0x1100, 0x0271: 0x1100, 0x0272: 0x1100, 0x0273: 0x1100, + // Block 0xa, offset 0x280 + 0x0292: 0x8800, + 0x02b0: 0x3000, 0x02b1: 0x3000, 0x02b2: 0x3000, 0x02b3: 0x3000, 0x02b4: 0x3000, 0x02b5: 0x3000, + 0x02b6: 0x3000, 0x02b7: 0x3000, 0x02b8: 0x3000, + // Block 0xb, offset 0x2c0 + 0x02d8: 0x3000, 0x02d9: 0x3000, 0x02da: 0x3000, 0x02db: 0x3000, 0x02dc: 0x3000, 0x02dd: 0x3000, + 0x02e0: 0x3000, 0x02e1: 0x3000, 0x02e2: 0x3000, 0x02e3: 0x3000, + 0x02e4: 0x3000, + // Block 0xc, offset 0x300 + 0x0300: 0x66e6, 0x0301: 0x66e6, 0x0302: 0x66e6, 0x0303: 0x66e6, 0x0304: 0x66e6, 0x0305: 0x00e6, + 0x0306: 0x66e6, 0x0307: 0x66e6, 0x0308: 0x66e6, 0x0309: 0x66e6, 0x030a: 0x66e6, 0x030b: 0x66e6, + 0x030c: 0x66e6, 0x030d: 0x00e6, 0x030e: 0x00e6, 0x030f: 0x66e6, 0x0310: 0x00e6, 0x0311: 0x66e6, + 0x0312: 0x00e6, 0x0313: 0x66e6, 0x0314: 0x66e6, 0x0315: 0x00e8, 0x0316: 0x00dc, 0x0317: 0x00dc, + 0x0318: 0x00dc, 0x0319: 0x00dc, 0x031a: 0x00e8, 0x031b: 0x66d8, 0x031c: 0x00dc, 0x031d: 0x00dc, + 0x031e: 0x00dc, 0x031f: 0x00dc, 0x0320: 0x00dc, 0x0321: 0x00ca, 0x0322: 0x00ca, 0x0323: 0x66dc, + 0x0324: 0x66dc, 0x0325: 0x66dc, 0x0326: 0x66dc, 0x0327: 0x66ca, 0x0328: 0x66ca, 0x0329: 0x00dc, + 0x032a: 0x00dc, 0x032b: 0x00dc, 0x032c: 0x00dc, 0x032d: 0x66dc, 0x032e: 0x66dc, 0x032f: 0x00dc, + 0x0330: 0x66dc, 0x0331: 0x66dc, 0x0332: 0x00dc, 0x0333: 0x00dc, 0x0334: 0x0001, 0x0335: 0x0001, + 0x0336: 0x0001, 0x0337: 0x0001, 0x0338: 0x6601, 0x0339: 0x00dc, 0x033a: 0x00dc, 0x033b: 0x00dc, + 0x033c: 0x00dc, 0x033d: 0x00e6, 0x033e: 0x00e6, 0x033f: 0x00e6, + // Block 0xd, offset 0x340 + 0x0340: 0x33e6, 0x0341: 0x33e6, 0x0342: 0x66e6, 0x0343: 0x33e6, 0x0344: 0x33e6, 0x0345: 0x66f0, + 0x0346: 0x00e6, 0x0347: 0x00dc, 0x0348: 0x00dc, 0x0349: 0x00dc, 0x034a: 0x00e6, 0x034b: 0x00e6, + 0x034c: 0x00e6, 0x034d: 0x00dc, 0x034e: 0x00dc, 0x0350: 0x00e6, 0x0351: 0x00e6, + 0x0352: 0x00e6, 0x0353: 0x00dc, 0x0354: 0x00dc, 0x0355: 0x00dc, 0x0356: 0x00dc, 0x0357: 0x00e6, + 0x0358: 0x00e8, 0x0359: 0x00dc, 0x035a: 0x00dc, 0x035b: 0x00e6, 0x035c: 0x00e9, 0x035d: 0x00ea, + 0x035e: 0x00ea, 0x035f: 0x00e9, 0x0360: 0x00ea, 0x0361: 0x00ea, 0x0362: 0x00e9, 0x0363: 0x00e6, + 0x0364: 0x00e6, 0x0365: 0x00e6, 0x0366: 0x00e6, 0x0367: 0x00e6, 0x0368: 0x00e6, 0x0369: 0x00e6, + 0x036a: 0x00e6, 0x036b: 0x00e6, 0x036c: 0x00e6, 0x036d: 0x00e6, 0x036e: 0x00e6, 0x036f: 0x00e6, + 0x0374: 0x3300, + 0x037a: 0x3000, + 0x037e: 0x3300, + // Block 0xe, offset 0x380 + 0x0384: 0x3000, 0x0385: 0x3100, + 0x0386: 0x1100, 0x0387: 0x3300, 0x0388: 0x1100, 0x0389: 0x1100, 0x038a: 0x1100, + 0x038c: 0x1100, 0x038e: 0x1100, 0x038f: 0x1100, 0x0390: 0x1100, 0x0391: 0x8800, + 0x0395: 0x8800, 0x0397: 0x8800, + 0x0399: 0x8800, + 0x039f: 0x8800, 0x03a1: 0x8800, + 0x03a5: 0x8800, 0x03a9: 0x8800, + 0x03aa: 0x1100, 0x03ab: 0x1100, 0x03ac: 0x9900, 0x03ad: 0x1100, 0x03ae: 0x9900, 0x03af: 0x1100, + 0x03b0: 0x1100, 0x03b1: 0x8800, 0x03b5: 0x8800, + 0x03b7: 0x8800, 0x03b9: 0x8800, + 0x03bf: 0x8800, + // Block 0xf, offset 0x3c0 + 0x03c1: 0x8800, 0x03c5: 0x8800, + 0x03c9: 0x8800, 0x03ca: 0x9900, 0x03cb: 0x9900, + 0x03cc: 0x1100, 0x03cd: 0x1100, 0x03ce: 0x9900, 0x03d0: 0x3000, 0x03d1: 0x3000, + 0x03d2: 0x3800, 0x03d3: 0x3100, 0x03d4: 0x3100, 0x03d5: 0x3000, 0x03d6: 0x3000, + 0x03f0: 0x3000, 0x03f1: 0x3000, 0x03f2: 0x3000, 0x03f4: 0x3000, 0x03f5: 0x3000, + 0x03f9: 0x3000, + // Block 0x10, offset 0x400 + 0x0400: 0x1100, 0x0401: 0x1100, 0x0403: 0x1100, + 0x0406: 0x8800, 0x0407: 0x1100, + 0x040c: 0x1100, 0x040d: 0x1100, 0x040e: 0x1100, 0x0410: 0x8800, + 0x0413: 0x8800, 0x0415: 0x8800, 0x0416: 0x8800, 0x0417: 0x8800, + 0x0418: 0x8800, 0x0419: 0x1100, 0x041a: 0x8800, + 0x041e: 0x8800, 0x0423: 0x8800, + 0x0427: 0x8800, + 0x042b: 0x8800, 0x042d: 0x8800, + 0x0430: 0x8800, 0x0433: 0x8800, 0x0435: 0x8800, + 0x0436: 0x8800, 0x0437: 0x8800, 0x0438: 0x8800, 0x0439: 0x1100, 0x043a: 0x8800, + 0x043e: 0x8800, + // Block 0x11, offset 0x440 + 0x0443: 0x8800, + 0x0447: 0x8800, 0x044b: 0x8800, + 0x044d: 0x8800, 0x0450: 0x1100, 0x0451: 0x1100, + 0x0453: 0x1100, 0x0456: 0x8800, 0x0457: 0x1100, + 0x045c: 0x1100, 0x045d: 0x1100, + 0x045e: 0x1100, + 0x0474: 0x8800, 0x0475: 0x8800, + 0x0476: 0x1100, 0x0477: 0x1100, + // Block 0x12, offset 0x480 + 0x0483: 0x00e6, 0x0484: 0x00e6, 0x0485: 0x00e6, + 0x0486: 0x00e6, 0x0487: 0x00e6, + // Block 0x13, offset 0x4c0 + 0x04c1: 0x1100, 0x04c2: 0x1100, + 0x04d0: 0x1100, 0x04d1: 0x1100, + 0x04d2: 0x1100, 0x04d3: 0x1100, 0x04d6: 0x1100, 0x04d7: 0x1100, + 0x04d8: 0x8800, 0x04d9: 0x8800, 0x04da: 0x1100, 0x04db: 0x1100, 0x04dc: 0x1100, 0x04dd: 0x1100, + 0x04de: 0x1100, 0x04df: 0x1100, 0x04e2: 0x1100, 0x04e3: 0x1100, + 0x04e4: 0x1100, 0x04e5: 0x1100, 0x04e6: 0x1100, 0x04e7: 0x1100, 0x04e8: 0x8800, 0x04e9: 0x8800, + 0x04ea: 0x1100, 0x04eb: 0x1100, 0x04ec: 0x1100, 0x04ed: 0x1100, 0x04ee: 0x1100, 0x04ef: 0x1100, + 0x04f0: 0x1100, 0x04f1: 0x1100, 0x04f2: 0x1100, 0x04f3: 0x1100, 0x04f4: 0x1100, 0x04f5: 0x1100, + 0x04f8: 0x1100, 0x04f9: 0x1100, + // Block 0x14, offset 0x500 + 0x0507: 0x3000, + 0x0511: 0x00dc, + 0x0512: 0x00e6, 0x0513: 0x00e6, 0x0514: 0x00e6, 0x0515: 0x00e6, 0x0516: 0x00dc, 0x0517: 0x00e6, + 0x0518: 0x00e6, 0x0519: 0x00e6, 0x051a: 0x00de, 0x051b: 0x00dc, 0x051c: 0x00e6, 0x051d: 0x00e6, + 0x051e: 0x00e6, 0x051f: 0x00e6, 0x0520: 0x00e6, 0x0521: 0x00e6, 0x0522: 0x00dc, 0x0523: 0x00dc, + 0x0524: 0x00dc, 0x0525: 0x00dc, 0x0526: 0x00dc, 0x0527: 0x00dc, 0x0528: 0x00e6, 0x0529: 0x00e6, + 0x052a: 0x00dc, 0x052b: 0x00e6, 0x052c: 0x00e6, 0x052d: 0x00de, 0x052e: 0x00e4, 0x052f: 0x00e6, + 0x0530: 0x000a, 0x0531: 0x000b, 0x0532: 0x000c, 0x0533: 0x000d, 0x0534: 0x000e, 0x0535: 0x000f, + 0x0536: 0x0010, 0x0537: 0x0011, 0x0538: 0x0012, 0x0539: 0x0013, 0x053a: 0x0013, 0x053b: 0x0014, + 0x053c: 0x0015, 0x053d: 0x0016, 0x053f: 0x0017, + // Block 0x15, offset 0x540 + 0x0541: 0x0018, 0x0542: 0x0019, 0x0544: 0x00e6, 0x0545: 0x00dc, + 0x0547: 0x0012, + // Block 0x16, offset 0x580 + 0x0590: 0x00e6, 0x0591: 0x00e6, + 0x0592: 0x00e6, 0x0593: 0x00e6, 0x0594: 0x00e6, 0x0595: 0x00e6, 0x0596: 0x00e6, 0x0597: 0x00e6, + 0x0598: 0x001e, 0x0599: 0x001f, 0x059a: 0x0020, + 0x05a2: 0x1100, 0x05a3: 0x1100, + 0x05a4: 0x1100, 0x05a5: 0x1100, 0x05a6: 0x1100, 0x05a7: 0x8800, + // Block 0x17, offset 0x5c0 + 0x05c8: 0x8800, 0x05ca: 0x8800, 0x05cb: 0x001b, + 0x05cc: 0x001c, 0x05cd: 0x001d, 0x05ce: 0x001e, 0x05cf: 0x001f, 0x05d0: 0x0020, 0x05d1: 0x0021, + 0x05d2: 0x0022, 0x05d3: 0x66e6, 0x05d4: 0x66e6, 0x05d5: 0x66dc, 0x05d6: 0x00dc, 0x05d7: 0x00e6, + 0x05d8: 0x00e6, 0x05d9: 0x00e6, 0x05da: 0x00e6, 0x05db: 0x00e6, 0x05dc: 0x00dc, 0x05dd: 0x00e6, + 0x05de: 0x00e6, 0x05df: 0x00dc, + 0x05f0: 0x0023, 0x05f5: 0x3000, + 0x05f6: 0x3000, 0x05f7: 0x3000, 0x05f8: 0x3000, + // Block 0x18, offset 0x600 + 0x0600: 0x1100, 0x0601: 0x8800, 0x0602: 0x1100, + 0x0612: 0x8800, 0x0613: 0x1100, 0x0615: 0x8800, 0x0616: 0x00e6, 0x0617: 0x00e6, + 0x0618: 0x00e6, 0x0619: 0x00e6, 0x061a: 0x00e6, 0x061b: 0x00e6, 0x061c: 0x00e6, + 0x061f: 0x00e6, 0x0620: 0x00e6, 0x0621: 0x00e6, 0x0622: 0x00e6, 0x0623: 0x00dc, + 0x0624: 0x00e6, 0x0627: 0x00e6, 0x0628: 0x00e6, + 0x062a: 0x00dc, 0x062b: 0x00e6, 0x062c: 0x00e6, 0x062d: 0x00dc, + // Block 0x19, offset 0x640 + 0x0651: 0x0024, + 0x0670: 0x00e6, 0x0671: 0x00dc, 0x0672: 0x00e6, 0x0673: 0x00e6, 0x0674: 0x00dc, 0x0675: 0x00e6, + 0x0676: 0x00e6, 0x0677: 0x00dc, 0x0678: 0x00dc, 0x0679: 0x00dc, 0x067a: 0x00e6, 0x067b: 0x00dc, + 0x067c: 0x00dc, 0x067d: 0x00e6, 0x067e: 0x00dc, 0x067f: 0x00e6, + // Block 0x1a, offset 0x680 + 0x0680: 0x00e6, 0x0681: 0x00e6, 0x0682: 0x00dc, 0x0683: 0x00e6, 0x0684: 0x00dc, 0x0685: 0x00e6, + 0x0686: 0x00dc, 0x0687: 0x00e6, 0x0688: 0x00dc, 0x0689: 0x00e6, 0x068a: 0x00e6, + // Block 0x1b, offset 0x6c0 + 0x06eb: 0x00e6, 0x06ec: 0x00e6, 0x06ed: 0x00e6, 0x06ee: 0x00e6, 0x06ef: 0x00e6, + 0x06f0: 0x00e6, 0x06f1: 0x00e6, 0x06f2: 0x00dc, 0x06f3: 0x00e6, + // Block 0x1c, offset 0x700 + 0x0716: 0x00e6, 0x0717: 0x00e6, + 0x0718: 0x00e6, 0x0719: 0x00e6, 0x071b: 0x00e6, 0x071c: 0x00e6, 0x071d: 0x00e6, + 0x071e: 0x00e6, 0x071f: 0x00e6, 0x0720: 0x00e6, 0x0721: 0x00e6, 0x0722: 0x00e6, 0x0723: 0x00e6, + 0x0725: 0x00e6, 0x0726: 0x00e6, 0x0727: 0x00e6, 0x0729: 0x00e6, + 0x072a: 0x00e6, 0x072b: 0x00e6, 0x072c: 0x00e6, 0x072d: 0x00e6, + // Block 0x1d, offset 0x740 + 0x0759: 0x00dc, 0x075a: 0x00dc, 0x075b: 0x00dc, + // Block 0x1e, offset 0x780 + 0x07a8: 0x8800, 0x07a9: 0x1100, + 0x07b0: 0x8800, 0x07b1: 0x1100, 0x07b3: 0x8800, 0x07b4: 0x1100, + 0x07bc: 0x6607, + // Block 0x1f, offset 0x7c0 + 0x07cd: 0x0009, 0x07d1: 0x00e6, + 0x07d2: 0x00dc, 0x07d3: 0x00e6, 0x07d4: 0x00e6, + 0x07d8: 0x3300, 0x07d9: 0x3300, 0x07da: 0x3300, 0x07db: 0x3300, 0x07dc: 0x3300, 0x07dd: 0x3300, + 0x07de: 0x3300, 0x07df: 0x3300, + // Block 0x20, offset 0x800 + 0x083c: 0x0007, 0x083e: 0x6600, + // Block 0x21, offset 0x840 + 0x0847: 0x8800, 0x084b: 0x1100, + 0x084c: 0x1100, 0x084d: 0x0009, + 0x0857: 0x6600, + 0x085c: 0x3300, 0x085d: 0x3300, + 0x085f: 0x3300, + // Block 0x22, offset 0x880 + 0x08b3: 0x3300, + 0x08b6: 0x3300, + 0x08bc: 0x0007, + // Block 0x23, offset 0x8c0 + 0x08cd: 0x0009, + 0x08d9: 0x3300, 0x08da: 0x3300, 0x08db: 0x3300, + 0x08de: 0x3300, + // Block 0x24, offset 0x900 + 0x093c: 0x0007, + // Block 0x25, offset 0x940 + 0x094d: 0x0009, + // Block 0x26, offset 0x980 + 0x0987: 0x8800, 0x0988: 0x1100, 0x098b: 0x1100, + 0x098c: 0x1100, 0x098d: 0x0009, + 0x0996: 0x6600, 0x0997: 0x6600, + 0x099c: 0x3300, 0x099d: 0x3300, + // Block 0x27, offset 0x9c0 + 0x09d2: 0x8800, 0x09d4: 0x1100, + 0x09fe: 0x6600, + // Block 0x28, offset 0xa00 + 0x0a06: 0x8800, 0x0a07: 0x8800, 0x0a0a: 0x1100, 0x0a0b: 0x1100, + 0x0a0c: 0x1100, 0x0a0d: 0x0009, + 0x0a17: 0x6600, + // Block 0x29, offset 0xa40 + 0x0a46: 0x8800, 0x0a48: 0x1100, + 0x0a4d: 0x0009, + 0x0a55: 0x0054, 0x0a56: 0x665b, + // Block 0x2a, offset 0xa80 + 0x0abc: 0x0007, 0x0abf: 0x8800, + // Block 0x2b, offset 0xac0 + 0x0ac0: 0x1100, 0x0ac2: 0x6600, + 0x0ac6: 0x8800, 0x0ac7: 0x1100, 0x0ac8: 0x1100, 0x0aca: 0x9900, 0x0acb: 0x1100, + 0x0acd: 0x0009, + 0x0ad5: 0x6600, 0x0ad6: 0x6600, + // Block 0x2c, offset 0xb00 + 0x0b3e: 0x6600, + // Block 0x2d, offset 0xb40 + 0x0b4a: 0x6609, + 0x0b4f: 0x6600, + 0x0b59: 0x8800, 0x0b5a: 0x1100, 0x0b5c: 0x9900, 0x0b5d: 0x1100, + 0x0b5e: 0x1100, 0x0b5f: 0x6600, + // Block 0x2e, offset 0xb80 + 0x0bb3: 0x3000, + 0x0bb8: 0x0067, 0x0bb9: 0x0067, 0x0bba: 0x0009, + // Block 0x2f, offset 0xbc0 + 0x0bc8: 0x006b, 0x0bc9: 0x006b, 0x0bca: 0x006b, 0x0bcb: 0x006b, + // Block 0x30, offset 0xc00 + 0x0c33: 0x3000, + 0x0c38: 0x0076, 0x0c39: 0x0076, + // Block 0x31, offset 0xc40 + 0x0c48: 0x007a, 0x0c49: 0x007a, 0x0c4a: 0x007a, 0x0c4b: 0x007a, + 0x0c5c: 0x3000, 0x0c5d: 0x3000, + // Block 0x32, offset 0xc80 + 0x0c8c: 0x3000, + 0x0c98: 0x00dc, 0x0c99: 0x00dc, + 0x0cb5: 0x00dc, + 0x0cb7: 0x00dc, 0x0cb9: 0x00d8, + // Block 0x33, offset 0xcc0 + 0x0cc3: 0x3300, + 0x0ccd: 0x3300, + 0x0cd2: 0x3300, 0x0cd7: 0x3300, + 0x0cdc: 0x3300, + 0x0ce9: 0x3300, + 0x0cf1: 0x0081, 0x0cf2: 0x0082, 0x0cf3: 0x3300, 0x0cf4: 0x0084, 0x0cf5: 0x3300, + 0x0cf6: 0x3300, 0x0cf7: 0x3000, 0x0cf8: 0x3300, 0x0cf9: 0x3000, 0x0cfa: 0x0082, 0x0cfb: 0x0082, + 0x0cfc: 0x0082, 0x0cfd: 0x0082, + // Block 0x34, offset 0xd00 + 0x0d00: 0x0082, 0x0d01: 0x3300, 0x0d02: 0x00e6, 0x0d03: 0x00e6, 0x0d04: 0x0009, + 0x0d06: 0x00e6, 0x0d07: 0x00e6, + 0x0d13: 0x3300, + 0x0d1d: 0x3300, + 0x0d22: 0x3300, + 0x0d27: 0x3300, + 0x0d2c: 0x3300, + 0x0d39: 0x3300, + // Block 0x35, offset 0xd40 + 0x0d46: 0x00dc, + // Block 0x36, offset 0xd80 + 0x0da5: 0x8800, 0x0da6: 0x1100, + 0x0dae: 0x6600, + 0x0db7: 0x0007, 0x0db9: 0x0009, 0x0dba: 0x0009, + // Block 0x37, offset 0xdc0 + 0x0dcd: 0x00dc, + // Block 0x38, offset 0xe00 + 0x0e3c: 0x3000, + // Block 0x39, offset 0xe40 + 0x0e61: 0x6600, 0x0e62: 0x6600, 0x0e63: 0x6600, + 0x0e64: 0x6600, 0x0e65: 0x6600, 0x0e66: 0x6600, 0x0e67: 0x6600, 0x0e68: 0x6600, 0x0e69: 0x6600, + 0x0e6a: 0x6600, 0x0e6b: 0x6600, 0x0e6c: 0x6600, 0x0e6d: 0x6600, 0x0e6e: 0x6600, 0x0e6f: 0x6600, + 0x0e70: 0x6600, 0x0e71: 0x6600, 0x0e72: 0x6600, 0x0e73: 0x6600, 0x0e74: 0x6600, 0x0e75: 0x6600, + // Block 0x3a, offset 0xe80 + 0x0ea8: 0x6600, 0x0ea9: 0x6600, + 0x0eaa: 0x6600, 0x0eab: 0x6600, 0x0eac: 0x6600, 0x0ead: 0x6600, 0x0eae: 0x6600, 0x0eaf: 0x6600, + 0x0eb0: 0x6600, 0x0eb1: 0x6600, 0x0eb2: 0x6600, 0x0eb3: 0x6600, 0x0eb4: 0x6600, 0x0eb5: 0x6600, + 0x0eb6: 0x6600, 0x0eb7: 0x6600, 0x0eb8: 0x6600, 0x0eb9: 0x6600, 0x0eba: 0x6600, 0x0ebb: 0x6600, + 0x0ebc: 0x6600, 0x0ebd: 0x6600, 0x0ebe: 0x6600, 0x0ebf: 0x6600, + // Block 0x3b, offset 0xec0 + 0x0ec0: 0x6600, 0x0ec1: 0x6600, 0x0ec2: 0x6600, + // Block 0x3c, offset 0xf00 + 0x0f1d: 0x00e6, + 0x0f1e: 0x00e6, 0x0f1f: 0x00e6, + // Block 0x3d, offset 0xf40 + 0x0f54: 0x0009, + 0x0f74: 0x0009, + // Block 0x3e, offset 0xf80 + 0x0f92: 0x0009, + 0x0f9d: 0x00e6, + // Block 0x3f, offset 0xfc0 + 0x0fe9: 0x00e4, + // Block 0x40, offset 0x1000 + 0x1039: 0x00de, 0x103a: 0x00e6, 0x103b: 0x00dc, + // Block 0x41, offset 0x1040 + 0x1057: 0x00e6, + 0x1058: 0x00dc, + // Block 0x42, offset 0x1080 + 0x10a0: 0x0009, + 0x10b5: 0x00e6, + 0x10b6: 0x00e6, 0x10b7: 0x00e6, 0x10b8: 0x00e6, 0x10b9: 0x00e6, 0x10ba: 0x00e6, 0x10bb: 0x00e6, + 0x10bc: 0x00e6, 0x10bf: 0x00dc, + // Block 0x43, offset 0x10c0 + 0x10c5: 0x8800, + 0x10c6: 0x1100, 0x10c7: 0x8800, 0x10c8: 0x1100, 0x10c9: 0x8800, 0x10ca: 0x1100, 0x10cb: 0x8800, + 0x10cc: 0x1100, 0x10cd: 0x8800, 0x10ce: 0x1100, 0x10d1: 0x8800, + 0x10d2: 0x1100, + 0x10f4: 0x0007, 0x10f5: 0x6600, + 0x10fa: 0x8800, 0x10fb: 0x1100, + 0x10fc: 0x8800, 0x10fd: 0x1100, 0x10fe: 0x8800, 0x10ff: 0x8800, + // Block 0x44, offset 0x1100 + 0x1100: 0x1100, 0x1101: 0x1100, 0x1102: 0x8800, 0x1103: 0x1100, 0x1104: 0x0009, + 0x112b: 0x00e6, 0x112c: 0x00dc, 0x112d: 0x00e6, 0x112e: 0x00e6, 0x112f: 0x00e6, + 0x1130: 0x00e6, 0x1131: 0x00e6, 0x1132: 0x00e6, 0x1133: 0x00e6, + // Block 0x45, offset 0x1140 + 0x116a: 0x0009, + // Block 0x46, offset 0x1180 + 0x11a6: 0x0007, + 0x11b2: 0x0009, 0x11b3: 0x0009, + // Block 0x47, offset 0x11c0 + 0x11f7: 0x0007, + // Block 0x48, offset 0x1200 + 0x1210: 0x00e6, 0x1211: 0x00e6, + 0x1212: 0x00e6, 0x1214: 0x0001, 0x1215: 0x00dc, 0x1216: 0x00dc, 0x1217: 0x00dc, + 0x1218: 0x00dc, 0x1219: 0x00dc, 0x121a: 0x00e6, 0x121b: 0x00e6, 0x121c: 0x00dc, 0x121d: 0x00dc, + 0x121e: 0x00dc, 0x121f: 0x00dc, 0x1220: 0x00e6, 0x1222: 0x0001, 0x1223: 0x0001, + 0x1224: 0x0001, 0x1225: 0x0001, 0x1226: 0x0001, 0x1227: 0x0001, 0x1228: 0x0001, + 0x122d: 0x00dc, + // Block 0x49, offset 0x1240 + 0x126c: 0x3000, 0x126d: 0x3000, 0x126e: 0x3000, + 0x1270: 0x3000, 0x1271: 0x3000, 0x1272: 0x3000, 0x1273: 0x3000, 0x1274: 0x3000, 0x1275: 0x3000, + 0x1276: 0x3000, 0x1277: 0x3000, 0x1278: 0x3000, 0x1279: 0x3000, 0x127a: 0x3000, + 0x127c: 0x3000, 0x127d: 0x3000, 0x127e: 0x3000, 0x127f: 0x3000, + // Block 0x4a, offset 0x1280 + 0x1280: 0x3000, 0x1281: 0x3000, 0x1282: 0x3000, 0x1283: 0x3000, 0x1284: 0x3000, 0x1285: 0x3000, + 0x1286: 0x3000, 0x1287: 0x3000, 0x1288: 0x3000, 0x1289: 0x3000, 0x128a: 0x3000, 0x128b: 0x3000, + 0x128c: 0x3000, 0x128d: 0x3000, 0x128f: 0x3000, 0x1290: 0x3000, 0x1291: 0x3000, + 0x1292: 0x3000, 0x1293: 0x3000, 0x1294: 0x3000, 0x1295: 0x3000, 0x1296: 0x3000, 0x1297: 0x3000, + 0x1298: 0x3000, 0x1299: 0x3000, 0x129a: 0x3000, 0x129b: 0x3000, 0x129c: 0x3000, 0x129d: 0x3000, + 0x129e: 0x3000, 0x129f: 0x3000, 0x12a0: 0x3000, 0x12a1: 0x3000, 0x12a2: 0x3000, 0x12a3: 0x3000, + 0x12a4: 0x3000, 0x12a5: 0x3000, 0x12a6: 0x3000, 0x12a7: 0x3000, 0x12a8: 0x3000, 0x12a9: 0x3000, + 0x12aa: 0x3000, + 0x12b8: 0x3000, + // Block 0x4b, offset 0x12c0 + 0x12db: 0x3000, 0x12dc: 0x3000, 0x12dd: 0x3000, + 0x12de: 0x3000, 0x12df: 0x3000, 0x12e0: 0x3000, 0x12e1: 0x3000, 0x12e2: 0x3000, 0x12e3: 0x3000, + 0x12e4: 0x3000, 0x12e5: 0x3000, 0x12e6: 0x3000, 0x12e7: 0x3000, 0x12e8: 0x3000, 0x12e9: 0x3000, + 0x12ea: 0x3000, 0x12eb: 0x3000, 0x12ec: 0x3000, 0x12ed: 0x3000, 0x12ee: 0x3000, 0x12ef: 0x3000, + 0x12f0: 0x3000, 0x12f1: 0x3000, 0x12f2: 0x3000, 0x12f3: 0x3000, 0x12f4: 0x3000, 0x12f5: 0x3000, + 0x12f6: 0x3000, 0x12f7: 0x3000, 0x12f8: 0x3000, 0x12f9: 0x3000, 0x12fa: 0x3000, 0x12fb: 0x3000, + 0x12fc: 0x3000, 0x12fd: 0x3000, 0x12fe: 0x3000, 0x12ff: 0x3000, + // Block 0x4c, offset 0x1300 + 0x1300: 0x00e6, 0x1301: 0x00e6, 0x1302: 0x00dc, 0x1303: 0x00e6, 0x1304: 0x00e6, 0x1305: 0x00e6, + 0x1306: 0x00e6, 0x1307: 0x00e6, 0x1308: 0x00e6, 0x1309: 0x00e6, 0x130a: 0x00dc, 0x130b: 0x00e6, + 0x130c: 0x00e6, 0x130d: 0x00ea, 0x130e: 0x00d6, 0x130f: 0x00dc, 0x1310: 0x00ca, 0x1311: 0x00e6, + 0x1312: 0x00e6, 0x1313: 0x00e6, 0x1314: 0x00e6, 0x1315: 0x00e6, 0x1316: 0x00e6, 0x1317: 0x00e6, + 0x1318: 0x00e6, 0x1319: 0x00e6, 0x131a: 0x00e6, 0x131b: 0x00e6, 0x131c: 0x00e6, 0x131d: 0x00e6, + 0x131e: 0x00e6, 0x131f: 0x00e6, 0x1320: 0x00e6, 0x1321: 0x00e6, 0x1322: 0x00e6, 0x1323: 0x00e6, + 0x1324: 0x00e6, 0x1325: 0x00e6, 0x1326: 0x00e6, + 0x133c: 0x00e9, 0x133d: 0x00dc, 0x133e: 0x00e6, 0x133f: 0x00dc, + // Block 0x4d, offset 0x1340 + 0x1340: 0x1100, 0x1341: 0x1100, 0x1342: 0x1100, 0x1343: 0x1100, 0x1344: 0x1100, 0x1345: 0x1100, + 0x1346: 0x1100, 0x1347: 0x1100, 0x1348: 0x1100, 0x1349: 0x1100, 0x134a: 0x1100, 0x134b: 0x1100, + 0x134c: 0x1100, 0x134d: 0x1100, 0x134e: 0x1100, 0x134f: 0x1100, 0x1350: 0x1100, 0x1351: 0x1100, + 0x1352: 0x1100, 0x1353: 0x1100, 0x1354: 0x1100, 0x1355: 0x1100, 0x1356: 0x1100, 0x1357: 0x1100, + 0x1358: 0x1100, 0x1359: 0x1100, 0x135a: 0x1100, 0x135b: 0x1100, 0x135c: 0x1100, 0x135d: 0x1100, + 0x135e: 0x1100, 0x135f: 0x1100, 0x1360: 0x1100, 0x1361: 0x1100, 0x1362: 0x1100, 0x1363: 0x1100, + 0x1364: 0x1100, 0x1365: 0x1100, 0x1366: 0x1100, 0x1367: 0x1100, 0x1368: 0x1100, 0x1369: 0x1100, + 0x136a: 0x1100, 0x136b: 0x1100, 0x136c: 0x1100, 0x136d: 0x1100, 0x136e: 0x1100, 0x136f: 0x1100, + 0x1370: 0x1100, 0x1371: 0x1100, 0x1372: 0x1100, 0x1373: 0x1100, 0x1374: 0x1100, 0x1375: 0x1100, + 0x1376: 0x9900, 0x1377: 0x9900, 0x1378: 0x1100, 0x1379: 0x1100, 0x137a: 0x1100, 0x137b: 0x1100, + 0x137c: 0x1100, 0x137d: 0x1100, 0x137e: 0x1100, 0x137f: 0x1100, + // Block 0x4e, offset 0x1380 + 0x1380: 0x1100, 0x1381: 0x1100, 0x1382: 0x1100, 0x1383: 0x1100, 0x1384: 0x1100, 0x1385: 0x1100, + 0x1386: 0x1100, 0x1387: 0x1100, 0x1388: 0x1100, 0x1389: 0x1100, 0x138a: 0x1100, 0x138b: 0x1100, + 0x138c: 0x1100, 0x138d: 0x1100, 0x138e: 0x1100, 0x138f: 0x1100, 0x1390: 0x1100, 0x1391: 0x1100, + 0x1392: 0x1100, 0x1393: 0x1100, 0x1394: 0x1100, 0x1395: 0x1100, 0x1396: 0x1100, 0x1397: 0x1100, + 0x1398: 0x1100, 0x1399: 0x1100, 0x139a: 0x9900, 0x139b: 0x9900, 0x139c: 0x1100, 0x139d: 0x1100, + 0x139e: 0x1100, 0x139f: 0x1100, 0x13a0: 0x1100, 0x13a1: 0x1100, 0x13a2: 0x9900, 0x13a3: 0x9900, + 0x13a4: 0x1100, 0x13a5: 0x1100, 0x13a6: 0x1100, 0x13a7: 0x1100, 0x13a8: 0x1100, 0x13a9: 0x1100, + 0x13aa: 0x1100, 0x13ab: 0x1100, 0x13ac: 0x1100, 0x13ad: 0x1100, 0x13ae: 0x1100, 0x13af: 0x1100, + 0x13b0: 0x1100, 0x13b1: 0x1100, 0x13b2: 0x1100, 0x13b3: 0x1100, 0x13b4: 0x1100, 0x13b5: 0x1100, + 0x13b6: 0x1100, 0x13b7: 0x1100, 0x13b8: 0x1100, 0x13b9: 0x1100, 0x13ba: 0x1100, 0x13bb: 0x1100, + 0x13bc: 0x1100, 0x13bd: 0x1100, 0x13be: 0x1100, 0x13bf: 0x1100, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x1100, 0x13c1: 0x1100, 0x13c2: 0x1100, 0x13c3: 0x1100, 0x13c4: 0x1100, 0x13c5: 0x1100, + 0x13c6: 0x1100, 0x13c7: 0x1100, 0x13c8: 0x1100, 0x13c9: 0x1100, 0x13ca: 0x1100, 0x13cb: 0x1100, + 0x13cc: 0x1100, 0x13cd: 0x1100, 0x13ce: 0x1100, 0x13cf: 0x1100, 0x13d0: 0x1100, 0x13d1: 0x1100, + 0x13d2: 0x1100, 0x13d3: 0x1100, 0x13d4: 0x1100, 0x13d5: 0x1100, 0x13d6: 0x1100, 0x13d7: 0x1100, + 0x13d8: 0x1100, 0x13d9: 0x1100, 0x13da: 0x3000, 0x13db: 0x3100, + 0x13e0: 0x9900, 0x13e1: 0x9900, 0x13e2: 0x1100, 0x13e3: 0x1100, + 0x13e4: 0x1100, 0x13e5: 0x1100, 0x13e6: 0x1100, 0x13e7: 0x1100, 0x13e8: 0x1100, 0x13e9: 0x1100, + 0x13ea: 0x1100, 0x13eb: 0x1100, 0x13ec: 0x1100, 0x13ed: 0x1100, 0x13ee: 0x1100, 0x13ef: 0x1100, + 0x13f0: 0x1100, 0x13f1: 0x1100, 0x13f2: 0x1100, 0x13f3: 0x1100, 0x13f4: 0x1100, 0x13f5: 0x1100, + 0x13f6: 0x1100, 0x13f7: 0x1100, 0x13f8: 0x9900, 0x13f9: 0x9900, 0x13fa: 0x1100, 0x13fb: 0x1100, + 0x13fc: 0x1100, 0x13fd: 0x1100, 0x13fe: 0x1100, 0x13ff: 0x1100, + // Block 0x50, offset 0x1400 + 0x1400: 0x1100, 0x1401: 0x1100, 0x1402: 0x1100, 0x1403: 0x1100, 0x1404: 0x1100, 0x1405: 0x1100, + 0x1406: 0x1100, 0x1407: 0x1100, 0x1408: 0x1100, 0x1409: 0x1100, 0x140a: 0x1100, 0x140b: 0x1100, + 0x140c: 0x9900, 0x140d: 0x9900, 0x140e: 0x1100, 0x140f: 0x1100, 0x1410: 0x1100, 0x1411: 0x1100, + 0x1412: 0x1100, 0x1413: 0x1100, 0x1414: 0x1100, 0x1415: 0x1100, 0x1416: 0x1100, 0x1417: 0x1100, + 0x1418: 0x1100, 0x1419: 0x1100, 0x141a: 0x1100, 0x141b: 0x1100, 0x141c: 0x1100, 0x141d: 0x1100, + 0x141e: 0x1100, 0x141f: 0x1100, 0x1420: 0x1100, 0x1421: 0x1100, 0x1422: 0x1100, 0x1423: 0x1100, + 0x1424: 0x1100, 0x1425: 0x1100, 0x1426: 0x1100, 0x1427: 0x1100, 0x1428: 0x1100, 0x1429: 0x1100, + 0x142a: 0x1100, 0x142b: 0x1100, 0x142c: 0x1100, 0x142d: 0x1100, 0x142e: 0x1100, 0x142f: 0x1100, + 0x1430: 0x1100, 0x1431: 0x1100, 0x1432: 0x1100, 0x1433: 0x1100, 0x1434: 0x1100, 0x1435: 0x1100, + 0x1436: 0x1100, 0x1437: 0x1100, 0x1438: 0x1100, 0x1439: 0x1100, + // Block 0x51, offset 0x1440 + 0x1440: 0x9900, 0x1441: 0x9900, 0x1442: 0x9900, 0x1443: 0x9900, 0x1444: 0x9900, 0x1445: 0x9900, + 0x1446: 0x9900, 0x1447: 0x9900, 0x1448: 0x9900, 0x1449: 0x9900, 0x144a: 0x9900, 0x144b: 0x9900, + 0x144c: 0x9900, 0x144d: 0x9900, 0x144e: 0x9900, 0x144f: 0x9900, 0x1450: 0x9900, 0x1451: 0x9900, + 0x1452: 0x1100, 0x1453: 0x1100, 0x1454: 0x1100, 0x1455: 0x1100, + 0x1458: 0x9900, 0x1459: 0x9900, 0x145a: 0x1100, 0x145b: 0x1100, 0x145c: 0x1100, 0x145d: 0x1100, + 0x1460: 0x9900, 0x1461: 0x9900, 0x1462: 0x9900, 0x1463: 0x9900, + 0x1464: 0x9900, 0x1465: 0x9900, 0x1466: 0x9900, 0x1467: 0x9900, 0x1468: 0x9900, 0x1469: 0x9900, + 0x146a: 0x9900, 0x146b: 0x9900, 0x146c: 0x9900, 0x146d: 0x9900, 0x146e: 0x9900, 0x146f: 0x9900, + 0x1470: 0x9900, 0x1471: 0x9900, 0x1472: 0x1100, 0x1473: 0x1100, 0x1474: 0x1100, 0x1475: 0x1100, + 0x1476: 0x1100, 0x1477: 0x1100, 0x1478: 0x9900, 0x1479: 0x9900, 0x147a: 0x1100, 0x147b: 0x1100, + 0x147c: 0x1100, 0x147d: 0x1100, 0x147e: 0x1100, 0x147f: 0x1100, + // Block 0x52, offset 0x1480 + 0x1480: 0x9900, 0x1481: 0x9900, 0x1482: 0x1100, 0x1483: 0x1100, 0x1484: 0x1100, 0x1485: 0x1100, + 0x1488: 0x9900, 0x1489: 0x9900, 0x148a: 0x1100, 0x148b: 0x1100, + 0x148c: 0x1100, 0x148d: 0x1100, 0x1490: 0x9900, 0x1491: 0x9900, + 0x1492: 0x1100, 0x1493: 0x1100, 0x1494: 0x1100, 0x1495: 0x1100, 0x1496: 0x1100, 0x1497: 0x1100, + 0x1499: 0x9900, 0x149b: 0x1100, 0x149d: 0x1100, + 0x149f: 0x1100, 0x14a0: 0x9900, 0x14a1: 0x9900, 0x14a2: 0x9900, 0x14a3: 0x9900, + 0x14a4: 0x9900, 0x14a5: 0x9900, 0x14a6: 0x9900, 0x14a7: 0x9900, 0x14a8: 0x9900, 0x14a9: 0x9900, + 0x14aa: 0x9900, 0x14ab: 0x9900, 0x14ac: 0x9900, 0x14ad: 0x9900, 0x14ae: 0x9900, 0x14af: 0x9900, + 0x14b0: 0x9900, 0x14b1: 0x3300, 0x14b2: 0x1100, 0x14b3: 0x3300, 0x14b4: 0x9900, 0x14b5: 0x3300, + 0x14b6: 0x1100, 0x14b7: 0x3300, 0x14b8: 0x1100, 0x14b9: 0x3300, 0x14ba: 0x1100, 0x14bb: 0x3300, + 0x14bc: 0x9900, 0x14bd: 0x3300, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x1100, 0x14c1: 0x1100, 0x14c2: 0x1100, 0x14c3: 0x1100, 0x14c4: 0x1100, 0x14c5: 0x1100, + 0x14c6: 0x1100, 0x14c7: 0x1100, 0x14c8: 0x1100, 0x14c9: 0x1100, 0x14ca: 0x1100, 0x14cb: 0x1100, + 0x14cc: 0x1100, 0x14cd: 0x1100, 0x14ce: 0x1100, 0x14cf: 0x1100, 0x14d0: 0x1100, 0x14d1: 0x1100, + 0x14d2: 0x1100, 0x14d3: 0x1100, 0x14d4: 0x1100, 0x14d5: 0x1100, 0x14d6: 0x1100, 0x14d7: 0x1100, + 0x14d8: 0x1100, 0x14d9: 0x1100, 0x14da: 0x1100, 0x14db: 0x1100, 0x14dc: 0x1100, 0x14dd: 0x1100, + 0x14de: 0x1100, 0x14df: 0x1100, 0x14e0: 0x1100, 0x14e1: 0x1100, 0x14e2: 0x1100, 0x14e3: 0x1100, + 0x14e4: 0x1100, 0x14e5: 0x1100, 0x14e6: 0x1100, 0x14e7: 0x1100, 0x14e8: 0x1100, 0x14e9: 0x1100, + 0x14ea: 0x1100, 0x14eb: 0x1100, 0x14ec: 0x1100, 0x14ed: 0x1100, 0x14ee: 0x1100, 0x14ef: 0x1100, + 0x14f0: 0x1100, 0x14f1: 0x1100, 0x14f2: 0x1100, 0x14f3: 0x1100, 0x14f4: 0x1100, + 0x14f6: 0x9900, 0x14f7: 0x1100, 0x14f8: 0x1100, 0x14f9: 0x1100, 0x14fa: 0x1100, 0x14fb: 0x3300, + 0x14fc: 0x1100, 0x14fd: 0x3000, 0x14fe: 0x3300, 0x14ff: 0x3800, + // Block 0x54, offset 0x1500 + 0x1500: 0x3000, 0x1501: 0x3100, 0x1502: 0x1100, 0x1503: 0x1100, 0x1504: 0x1100, + 0x1506: 0x9900, 0x1507: 0x1100, 0x1508: 0x1100, 0x1509: 0x3300, 0x150a: 0x1100, 0x150b: 0x3300, + 0x150c: 0x1100, 0x150d: 0x3100, 0x150e: 0x3100, 0x150f: 0x3100, 0x1510: 0x1100, 0x1511: 0x1100, + 0x1512: 0x1100, 0x1513: 0x3300, 0x1516: 0x1100, 0x1517: 0x1100, + 0x1518: 0x1100, 0x1519: 0x1100, 0x151a: 0x1100, 0x151b: 0x3300, 0x151d: 0x3100, + 0x151e: 0x3100, 0x151f: 0x3100, 0x1520: 0x1100, 0x1521: 0x1100, 0x1522: 0x1100, 0x1523: 0x3300, + 0x1524: 0x1100, 0x1525: 0x1100, 0x1526: 0x1100, 0x1527: 0x1100, 0x1528: 0x1100, 0x1529: 0x1100, + 0x152a: 0x1100, 0x152b: 0x3300, 0x152c: 0x1100, 0x152d: 0x3100, 0x152e: 0x3300, 0x152f: 0x3300, + 0x1532: 0x1100, 0x1533: 0x1100, 0x1534: 0x1100, + 0x1536: 0x9900, 0x1537: 0x1100, 0x1538: 0x1100, 0x1539: 0x3300, 0x153a: 0x1100, 0x153b: 0x3300, + 0x153c: 0x1100, 0x153d: 0x3300, 0x153e: 0x3800, + // Block 0x55, offset 0x1540 + 0x1540: 0x3300, 0x1541: 0x3300, 0x1542: 0x3000, 0x1543: 0x3000, 0x1544: 0x3000, 0x1545: 0x3000, + 0x1546: 0x3000, 0x1547: 0x3000, 0x1548: 0x3000, 0x1549: 0x3000, 0x154a: 0x3000, + 0x1551: 0x3000, + 0x1557: 0x3000, + 0x1564: 0x3000, 0x1565: 0x3000, 0x1566: 0x3000, + 0x156f: 0x3000, + 0x1573: 0x3000, 0x1574: 0x3000, + 0x1576: 0x3000, 0x1577: 0x3000, + 0x157c: 0x3000, 0x157e: 0x3000, + // Block 0x56, offset 0x1580 + 0x1587: 0x3000, 0x1588: 0x3000, 0x1589: 0x3000, + 0x1597: 0x3000, + 0x159f: 0x3000, + 0x15b0: 0x3000, 0x15b1: 0x3000, 0x15b4: 0x3000, 0x15b5: 0x3000, + 0x15b6: 0x3000, 0x15b7: 0x3000, 0x15b8: 0x3000, 0x15b9: 0x3000, 0x15ba: 0x3000, 0x15bb: 0x3000, + 0x15bc: 0x3000, 0x15bd: 0x3000, 0x15be: 0x3000, 0x15bf: 0x3000, + // Block 0x57, offset 0x15c0 + 0x15c0: 0x3000, 0x15c1: 0x3000, 0x15c2: 0x3000, 0x15c3: 0x3000, 0x15c4: 0x3000, 0x15c5: 0x3000, + 0x15c6: 0x3000, 0x15c7: 0x3000, 0x15c8: 0x3000, 0x15c9: 0x3000, 0x15ca: 0x3000, 0x15cb: 0x3000, + 0x15cc: 0x3000, 0x15cd: 0x3000, 0x15ce: 0x3000, 0x15d0: 0x3000, 0x15d1: 0x3000, + 0x15d2: 0x3000, 0x15d3: 0x3000, 0x15d4: 0x3000, 0x15d5: 0x3000, 0x15d6: 0x3000, 0x15d7: 0x3000, + 0x15d8: 0x3000, 0x15d9: 0x3000, 0x15da: 0x3000, 0x15db: 0x3000, 0x15dc: 0x3000, + 0x15e8: 0x3000, + // Block 0x58, offset 0x1600 + 0x1610: 0x00e6, 0x1611: 0x00e6, + 0x1612: 0x0001, 0x1613: 0x0001, 0x1614: 0x00e6, 0x1615: 0x00e6, 0x1616: 0x00e6, 0x1617: 0x00e6, + 0x1618: 0x0001, 0x1619: 0x0001, 0x161a: 0x0001, 0x161b: 0x00e6, 0x161c: 0x00e6, + 0x1621: 0x00e6, + 0x1625: 0x0001, 0x1626: 0x0001, 0x1627: 0x00e6, 0x1628: 0x00dc, 0x1629: 0x00e6, + 0x162a: 0x0001, 0x162b: 0x0001, 0x162c: 0x00dc, 0x162d: 0x00dc, 0x162e: 0x00dc, 0x162f: 0x00dc, + 0x1630: 0x00e6, + // Block 0x59, offset 0x1640 + 0x1640: 0x3000, 0x1641: 0x3000, 0x1642: 0x3000, 0x1643: 0x3000, 0x1645: 0x3000, + 0x1646: 0x3000, 0x1647: 0x3000, 0x1649: 0x3000, 0x164a: 0x3000, 0x164b: 0x3000, + 0x164c: 0x3000, 0x164d: 0x3000, 0x164e: 0x3000, 0x164f: 0x3000, 0x1650: 0x3000, 0x1651: 0x3000, + 0x1652: 0x3000, 0x1653: 0x3000, 0x1655: 0x3000, 0x1656: 0x3000, + 0x1659: 0x3000, 0x165a: 0x3000, 0x165b: 0x3000, 0x165c: 0x3000, 0x165d: 0x3000, + 0x1660: 0x3000, 0x1661: 0x3000, 0x1662: 0x3000, + 0x1664: 0x3000, 0x1666: 0x3300, 0x1668: 0x3000, + 0x166a: 0x3300, 0x166b: 0x3300, 0x166c: 0x3000, 0x166d: 0x3000, 0x166f: 0x3000, + 0x1670: 0x3000, 0x1671: 0x3000, 0x1673: 0x3000, 0x1674: 0x3000, 0x1675: 0x3000, + 0x1676: 0x3000, 0x1677: 0x3000, 0x1678: 0x3000, 0x1679: 0x3000, 0x167b: 0x3000, + 0x167c: 0x3000, 0x167d: 0x3000, 0x167e: 0x3000, 0x167f: 0x3000, + // Block 0x5a, offset 0x1680 + 0x1680: 0x3000, 0x1685: 0x3000, + 0x1686: 0x3000, 0x1687: 0x3000, 0x1688: 0x3000, 0x1689: 0x3000, + 0x1690: 0x3000, 0x1691: 0x3000, + 0x1692: 0x3000, 0x1693: 0x3000, 0x1694: 0x3000, 0x1695: 0x3000, 0x1696: 0x3000, 0x1697: 0x3000, + 0x1698: 0x3000, 0x1699: 0x3000, 0x169a: 0x3000, 0x169b: 0x3000, 0x169c: 0x3000, 0x169d: 0x3000, + 0x169e: 0x3000, 0x169f: 0x3000, 0x16a0: 0x3000, 0x16a1: 0x3000, 0x16a2: 0x3000, 0x16a3: 0x3000, + 0x16a4: 0x3000, 0x16a5: 0x3000, 0x16a6: 0x3000, 0x16a7: 0x3000, 0x16a8: 0x3000, 0x16a9: 0x3000, + 0x16aa: 0x3000, 0x16ab: 0x3000, 0x16ac: 0x3000, 0x16ad: 0x3000, 0x16ae: 0x3000, 0x16af: 0x3000, + 0x16b0: 0x3000, 0x16b1: 0x3000, 0x16b2: 0x3000, 0x16b3: 0x3000, 0x16b4: 0x3000, 0x16b5: 0x3000, + 0x16b6: 0x3000, 0x16b7: 0x3000, 0x16b8: 0x3000, 0x16b9: 0x3000, 0x16ba: 0x3000, 0x16bb: 0x3000, + 0x16bc: 0x3000, 0x16bd: 0x3000, 0x16be: 0x3000, 0x16bf: 0x3000, + // Block 0x5b, offset 0x16c0 + 0x16c9: 0x3000, + 0x16d0: 0x8800, + 0x16d2: 0x8800, 0x16d4: 0x8800, + 0x16da: 0x1100, 0x16db: 0x1100, + 0x16ee: 0x1100, + // Block 0x5c, offset 0x1700 + 0x170d: 0x1100, 0x170e: 0x1100, 0x170f: 0x1100, 0x1710: 0x8800, + 0x1712: 0x8800, 0x1714: 0x8800, + // Block 0x5d, offset 0x1740 + 0x1743: 0x8800, 0x1744: 0x1100, + 0x1748: 0x8800, 0x1749: 0x1100, 0x174b: 0x8800, + 0x174c: 0x1100, + 0x1763: 0x8800, + 0x1764: 0x1100, 0x1765: 0x8800, 0x1766: 0x1100, + 0x176c: 0x3000, 0x176d: 0x3000, 0x176f: 0x3000, + 0x1770: 0x3000, + 0x177c: 0x8800, + // Block 0x5e, offset 0x1780 + 0x1781: 0x1100, 0x1783: 0x8800, 0x1784: 0x1100, 0x1785: 0x8800, + 0x1787: 0x1100, 0x1788: 0x8800, 0x1789: 0x1100, + 0x178d: 0x8800, + 0x17a0: 0x1100, 0x17a1: 0x8800, 0x17a2: 0x1100, + 0x17a4: 0x8800, 0x17a5: 0x8800, + 0x17ad: 0x1100, 0x17ae: 0x1100, 0x17af: 0x1100, + 0x17b0: 0x1100, 0x17b1: 0x1100, 0x17b2: 0x8800, 0x17b3: 0x8800, 0x17b4: 0x1100, 0x17b5: 0x1100, + 0x17b6: 0x8800, 0x17b7: 0x8800, 0x17b8: 0x1100, 0x17b9: 0x1100, 0x17ba: 0x8800, 0x17bb: 0x8800, + 0x17bc: 0x8800, 0x17bd: 0x8800, + // Block 0x5f, offset 0x17c0 + 0x17c0: 0x1100, 0x17c1: 0x1100, 0x17c2: 0x8800, 0x17c3: 0x8800, 0x17c4: 0x1100, 0x17c5: 0x1100, + 0x17c6: 0x8800, 0x17c7: 0x8800, 0x17c8: 0x1100, 0x17c9: 0x1100, + 0x17d1: 0x8800, + 0x17d2: 0x8800, + 0x17e2: 0x8800, + 0x17e8: 0x8800, 0x17e9: 0x8800, + 0x17eb: 0x8800, 0x17ec: 0x1100, 0x17ed: 0x1100, 0x17ee: 0x1100, 0x17ef: 0x1100, + 0x17f2: 0x8800, 0x17f3: 0x8800, 0x17f4: 0x8800, 0x17f5: 0x8800, + // Block 0x60, offset 0x1800 + 0x1820: 0x1100, 0x1821: 0x1100, 0x1822: 0x1100, 0x1823: 0x1100, + 0x182a: 0x1100, 0x182b: 0x1100, 0x182c: 0x1100, 0x182d: 0x1100, + // Block 0x61, offset 0x1840 + 0x1869: 0x3300, + 0x186a: 0x3300, + // Block 0x62, offset 0x1880 + 0x18a0: 0x3000, 0x18a1: 0x3000, 0x18a2: 0x3000, 0x18a3: 0x3000, + 0x18a4: 0x3000, 0x18a5: 0x3000, 0x18a6: 0x3000, 0x18a7: 0x3000, 0x18a8: 0x3000, 0x18a9: 0x3000, + 0x18aa: 0x3000, 0x18ab: 0x3000, 0x18ac: 0x3000, 0x18ad: 0x3000, 0x18ae: 0x3000, 0x18af: 0x3000, + 0x18b0: 0x3000, 0x18b1: 0x3000, 0x18b2: 0x3000, 0x18b3: 0x3000, 0x18b4: 0x3000, 0x18b5: 0x3000, + 0x18b6: 0x3000, 0x18b7: 0x3000, 0x18b8: 0x3000, 0x18b9: 0x3000, 0x18ba: 0x3000, 0x18bb: 0x3000, + 0x18bc: 0x3000, 0x18bd: 0x3000, 0x18be: 0x3000, 0x18bf: 0x3000, + // Block 0x63, offset 0x18c0 + 0x18c0: 0x3000, 0x18c1: 0x3000, 0x18c2: 0x3000, 0x18c3: 0x3000, 0x18c4: 0x3000, 0x18c5: 0x3000, + 0x18c6: 0x3000, 0x18c7: 0x3000, 0x18c8: 0x3000, 0x18c9: 0x3000, 0x18ca: 0x3000, 0x18cb: 0x3000, + 0x18cc: 0x3000, 0x18cd: 0x3000, 0x18ce: 0x3000, 0x18cf: 0x3000, 0x18d0: 0x3000, 0x18d1: 0x3000, + 0x18d2: 0x3000, 0x18d3: 0x3000, 0x18d4: 0x3000, 0x18d5: 0x3000, 0x18d6: 0x3000, 0x18d7: 0x3000, + 0x18d8: 0x3000, 0x18d9: 0x3000, 0x18da: 0x3000, 0x18db: 0x3000, 0x18dc: 0x3000, 0x18dd: 0x3000, + 0x18de: 0x3000, 0x18df: 0x3000, 0x18e0: 0x3000, 0x18e1: 0x3000, 0x18e2: 0x3000, 0x18e3: 0x3000, + 0x18e4: 0x3000, 0x18e5: 0x3000, 0x18e6: 0x3000, 0x18e7: 0x3000, 0x18e8: 0x3000, 0x18e9: 0x3000, + 0x18ea: 0x3000, 0x18eb: 0x3000, 0x18ec: 0x3000, 0x18ed: 0x3000, 0x18ee: 0x3000, 0x18ef: 0x3000, + 0x18f0: 0x3000, 0x18f1: 0x3000, 0x18f2: 0x3000, 0x18f3: 0x3000, 0x18f4: 0x3000, 0x18f5: 0x3000, + 0x18f6: 0x3000, 0x18f7: 0x3000, 0x18f8: 0x3000, 0x18f9: 0x3000, 0x18fa: 0x3000, 0x18fb: 0x3000, + 0x18fc: 0x3000, 0x18fd: 0x3000, 0x18fe: 0x3000, 0x18ff: 0x3000, + // Block 0x64, offset 0x1900 + 0x1900: 0x3000, 0x1901: 0x3000, 0x1902: 0x3000, 0x1903: 0x3000, 0x1904: 0x3000, 0x1905: 0x3000, + 0x1906: 0x3000, 0x1907: 0x3000, 0x1908: 0x3000, 0x1909: 0x3000, 0x190a: 0x3000, 0x190b: 0x3000, + 0x190c: 0x3000, 0x190d: 0x3000, 0x190e: 0x3000, 0x190f: 0x3000, 0x1910: 0x3000, 0x1911: 0x3000, + 0x1912: 0x3000, 0x1913: 0x3000, 0x1914: 0x3000, 0x1915: 0x3000, 0x1916: 0x3000, 0x1917: 0x3000, + 0x1918: 0x3000, 0x1919: 0x3000, 0x191a: 0x3000, 0x191b: 0x3000, 0x191c: 0x3000, 0x191d: 0x3000, + 0x191e: 0x3000, 0x191f: 0x3000, 0x1920: 0x3000, 0x1921: 0x3000, 0x1922: 0x3000, 0x1923: 0x3000, + 0x1924: 0x3000, 0x1925: 0x3000, 0x1926: 0x3000, 0x1927: 0x3000, 0x1928: 0x3000, 0x1929: 0x3000, + 0x192a: 0x3000, + // Block 0x65, offset 0x1940 + 0x194c: 0x3000, + // Block 0x66, offset 0x1980 + 0x19b4: 0x3000, 0x19b5: 0x3000, + 0x19b6: 0x3000, + // Block 0x67, offset 0x19c0 + 0x19dc: 0x3300, + // Block 0x68, offset 0x1a00 + 0x1a3c: 0x3000, 0x1a3d: 0x3000, + // Block 0x69, offset 0x1a40 + 0x1a6f: 0x00e6, + 0x1a70: 0x00e6, 0x1a71: 0x00e6, + // Block 0x6a, offset 0x1a80 + 0x1aaf: 0x3000, + 0x1abf: 0x0009, + // Block 0x6b, offset 0x1ac0 + 0x1ae0: 0x00e6, 0x1ae1: 0x00e6, 0x1ae2: 0x00e6, 0x1ae3: 0x00e6, + 0x1ae4: 0x00e6, 0x1ae5: 0x00e6, 0x1ae6: 0x00e6, 0x1ae7: 0x00e6, 0x1ae8: 0x00e6, 0x1ae9: 0x00e6, + 0x1aea: 0x00e6, 0x1aeb: 0x00e6, 0x1aec: 0x00e6, 0x1aed: 0x00e6, 0x1aee: 0x00e6, 0x1aef: 0x00e6, + 0x1af0: 0x00e6, 0x1af1: 0x00e6, 0x1af2: 0x00e6, 0x1af3: 0x00e6, 0x1af4: 0x00e6, 0x1af5: 0x00e6, + 0x1af6: 0x00e6, 0x1af7: 0x00e6, 0x1af8: 0x00e6, 0x1af9: 0x00e6, 0x1afa: 0x00e6, 0x1afb: 0x00e6, + 0x1afc: 0x00e6, 0x1afd: 0x00e6, 0x1afe: 0x00e6, 0x1aff: 0x00e6, + // Block 0x6c, offset 0x1b00 + 0x1b1f: 0x3000, + // Block 0x6d, offset 0x1b40 + 0x1b73: 0x3000, + // Block 0x6e, offset 0x1b80 + 0x1b80: 0x3000, 0x1b81: 0x3000, 0x1b82: 0x3000, 0x1b83: 0x3000, 0x1b84: 0x3000, 0x1b85: 0x3000, + 0x1b86: 0x3000, 0x1b87: 0x3000, 0x1b88: 0x3000, 0x1b89: 0x3000, 0x1b8a: 0x3000, 0x1b8b: 0x3000, + 0x1b8c: 0x3000, 0x1b8d: 0x3000, 0x1b8e: 0x3000, 0x1b8f: 0x3000, 0x1b90: 0x3000, 0x1b91: 0x3000, + 0x1b92: 0x3000, 0x1b93: 0x3000, 0x1b94: 0x3000, 0x1b95: 0x3000, + // Block 0x6f, offset 0x1bc0 + 0x1bc0: 0x3000, + 0x1bea: 0x00da, 0x1beb: 0x00e4, 0x1bec: 0x00e8, 0x1bed: 0x00de, 0x1bee: 0x00e0, 0x1bef: 0x00e0, + 0x1bf6: 0x3000, 0x1bf8: 0x3000, 0x1bf9: 0x3000, 0x1bfa: 0x3000, + // Block 0x70, offset 0x1c00 + 0x1c06: 0x8800, 0x1c0b: 0x8800, + 0x1c0c: 0x1100, 0x1c0d: 0x8800, 0x1c0e: 0x1100, 0x1c0f: 0x8800, 0x1c10: 0x1100, 0x1c11: 0x8800, + 0x1c12: 0x1100, 0x1c13: 0x8800, 0x1c14: 0x1100, 0x1c15: 0x8800, 0x1c16: 0x1100, 0x1c17: 0x8800, + 0x1c18: 0x1100, 0x1c19: 0x8800, 0x1c1a: 0x1100, 0x1c1b: 0x8800, 0x1c1c: 0x1100, 0x1c1d: 0x8800, + 0x1c1e: 0x1100, 0x1c1f: 0x8800, 0x1c20: 0x1100, 0x1c21: 0x8800, 0x1c22: 0x1100, + 0x1c24: 0x8800, 0x1c25: 0x1100, 0x1c26: 0x8800, 0x1c27: 0x1100, 0x1c28: 0x8800, 0x1c29: 0x1100, + 0x1c2f: 0x8800, + 0x1c30: 0x1100, 0x1c31: 0x1100, 0x1c32: 0x8800, 0x1c33: 0x1100, 0x1c34: 0x1100, 0x1c35: 0x8800, + 0x1c36: 0x1100, 0x1c37: 0x1100, 0x1c38: 0x8800, 0x1c39: 0x1100, 0x1c3a: 0x1100, 0x1c3b: 0x8800, + 0x1c3c: 0x1100, 0x1c3d: 0x1100, + // Block 0x71, offset 0x1c40 + 0x1c54: 0x1100, + 0x1c59: 0x6608, 0x1c5a: 0x6608, 0x1c5b: 0x3000, 0x1c5c: 0x3000, 0x1c5d: 0x8800, + 0x1c5e: 0x1100, 0x1c5f: 0x3000, + 0x1c66: 0x8800, + 0x1c6b: 0x8800, 0x1c6c: 0x1100, 0x1c6d: 0x8800, 0x1c6e: 0x1100, 0x1c6f: 0x8800, + 0x1c70: 0x1100, 0x1c71: 0x8800, 0x1c72: 0x1100, 0x1c73: 0x8800, 0x1c74: 0x1100, 0x1c75: 0x8800, + 0x1c76: 0x1100, 0x1c77: 0x8800, 0x1c78: 0x1100, 0x1c79: 0x8800, 0x1c7a: 0x1100, 0x1c7b: 0x8800, + 0x1c7c: 0x1100, 0x1c7d: 0x8800, 0x1c7e: 0x1100, 0x1c7f: 0x8800, + // Block 0x72, offset 0x1c80 + 0x1c80: 0x1100, 0x1c81: 0x8800, 0x1c82: 0x1100, 0x1c84: 0x8800, 0x1c85: 0x1100, + 0x1c86: 0x8800, 0x1c87: 0x1100, 0x1c88: 0x8800, 0x1c89: 0x1100, + 0x1c8f: 0x8800, 0x1c90: 0x1100, 0x1c91: 0x1100, + 0x1c92: 0x8800, 0x1c93: 0x1100, 0x1c94: 0x1100, 0x1c95: 0x8800, 0x1c96: 0x1100, 0x1c97: 0x1100, + 0x1c98: 0x8800, 0x1c99: 0x1100, 0x1c9a: 0x1100, 0x1c9b: 0x8800, 0x1c9c: 0x1100, 0x1c9d: 0x1100, + 0x1caf: 0x8800, + 0x1cb0: 0x8800, 0x1cb1: 0x8800, 0x1cb2: 0x8800, 0x1cb4: 0x1100, + 0x1cb7: 0x1100, 0x1cb8: 0x1100, 0x1cb9: 0x1100, 0x1cba: 0x1100, + 0x1cbd: 0x8800, 0x1cbe: 0x1100, 0x1cbf: 0x3000, + // Block 0x73, offset 0x1cc0 + 0x1cf1: 0x3000, 0x1cf2: 0x3000, 0x1cf3: 0x3000, 0x1cf4: 0x3000, 0x1cf5: 0x3000, + 0x1cf6: 0x3000, 0x1cf7: 0x3000, 0x1cf8: 0x3000, 0x1cf9: 0x3000, 0x1cfa: 0x3000, 0x1cfb: 0x3000, + 0x1cfc: 0x3000, 0x1cfd: 0x3000, 0x1cfe: 0x3000, 0x1cff: 0x3000, + // Block 0x74, offset 0x1d00 + 0x1d00: 0x3000, 0x1d01: 0x3000, 0x1d02: 0x3000, 0x1d03: 0x3000, 0x1d04: 0x3000, 0x1d05: 0x3000, + 0x1d06: 0x3000, 0x1d07: 0x3000, 0x1d08: 0x3000, 0x1d09: 0x3000, 0x1d0a: 0x3000, 0x1d0b: 0x3000, + 0x1d0c: 0x3000, 0x1d0d: 0x3000, 0x1d0e: 0x3000, + 0x1d12: 0x3000, 0x1d13: 0x3000, 0x1d14: 0x3000, 0x1d15: 0x3000, 0x1d16: 0x3000, 0x1d17: 0x3000, + 0x1d18: 0x3000, 0x1d19: 0x3000, 0x1d1a: 0x3000, 0x1d1b: 0x3000, 0x1d1c: 0x3000, 0x1d1d: 0x3000, + 0x1d1e: 0x3000, 0x1d1f: 0x3000, + // Block 0x75, offset 0x1d40 + 0x1d40: 0x3000, 0x1d41: 0x3000, 0x1d42: 0x3000, 0x1d43: 0x3000, 0x1d44: 0x3000, 0x1d45: 0x3000, + 0x1d46: 0x3000, 0x1d47: 0x3000, 0x1d48: 0x3000, 0x1d49: 0x3000, 0x1d4a: 0x3000, 0x1d4b: 0x3000, + 0x1d4c: 0x3000, 0x1d4d: 0x3000, 0x1d4e: 0x3000, 0x1d4f: 0x3000, 0x1d50: 0x3000, 0x1d51: 0x3000, + 0x1d52: 0x3000, 0x1d53: 0x3000, 0x1d54: 0x3000, 0x1d55: 0x3000, 0x1d56: 0x3000, 0x1d57: 0x3000, + 0x1d58: 0x3000, 0x1d59: 0x3000, 0x1d5a: 0x3000, 0x1d5b: 0x3000, 0x1d5c: 0x3000, 0x1d5d: 0x3000, + 0x1d5e: 0x3000, 0x1d60: 0x3000, 0x1d61: 0x3000, 0x1d62: 0x3000, 0x1d63: 0x3000, + 0x1d64: 0x3000, 0x1d65: 0x3000, 0x1d66: 0x3000, 0x1d67: 0x3000, 0x1d68: 0x3000, 0x1d69: 0x3000, + 0x1d6a: 0x3000, 0x1d6b: 0x3000, 0x1d6c: 0x3000, 0x1d6d: 0x3000, 0x1d6e: 0x3000, 0x1d6f: 0x3000, + 0x1d70: 0x3000, 0x1d71: 0x3000, 0x1d72: 0x3000, 0x1d73: 0x3000, 0x1d74: 0x3000, 0x1d75: 0x3000, + 0x1d76: 0x3000, 0x1d77: 0x3000, 0x1d78: 0x3000, 0x1d79: 0x3000, 0x1d7a: 0x3000, 0x1d7b: 0x3000, + 0x1d7c: 0x3000, 0x1d7d: 0x3000, 0x1d7e: 0x3000, 0x1d7f: 0x3000, + // Block 0x76, offset 0x1d80 + 0x1d80: 0x3000, 0x1d81: 0x3000, 0x1d82: 0x3000, 0x1d83: 0x3000, 0x1d84: 0x3000, 0x1d85: 0x3000, + 0x1d86: 0x3000, 0x1d87: 0x3000, + 0x1d90: 0x3000, 0x1d91: 0x3000, + 0x1d92: 0x3000, 0x1d93: 0x3000, 0x1d94: 0x3000, 0x1d95: 0x3000, 0x1d96: 0x3000, 0x1d97: 0x3000, + 0x1d98: 0x3000, 0x1d99: 0x3000, 0x1d9a: 0x3000, 0x1d9b: 0x3000, 0x1d9c: 0x3000, 0x1d9d: 0x3000, + 0x1d9e: 0x3000, 0x1d9f: 0x3000, 0x1da0: 0x3000, 0x1da1: 0x3000, 0x1da2: 0x3000, 0x1da3: 0x3000, + 0x1da4: 0x3000, 0x1da5: 0x3000, 0x1da6: 0x3000, 0x1da7: 0x3000, 0x1da8: 0x3000, 0x1da9: 0x3000, + 0x1daa: 0x3000, 0x1dab: 0x3000, 0x1dac: 0x3000, 0x1dad: 0x3000, 0x1dae: 0x3000, 0x1daf: 0x3000, + 0x1db0: 0x3000, 0x1db1: 0x3000, 0x1db2: 0x3000, 0x1db3: 0x3000, 0x1db4: 0x3000, 0x1db5: 0x3000, + 0x1db6: 0x3000, 0x1db7: 0x3000, 0x1db8: 0x3000, 0x1db9: 0x3000, 0x1dba: 0x3000, 0x1dbb: 0x3000, + 0x1dbc: 0x3000, 0x1dbd: 0x3000, 0x1dbe: 0x3000, + // Block 0x77, offset 0x1dc0 + 0x1dc0: 0x3000, 0x1dc1: 0x3000, 0x1dc2: 0x3000, 0x1dc3: 0x3000, 0x1dc4: 0x3000, 0x1dc5: 0x3000, + 0x1dc6: 0x3000, 0x1dc7: 0x3000, 0x1dc8: 0x3000, 0x1dc9: 0x3000, 0x1dca: 0x3000, 0x1dcb: 0x3000, + 0x1dcc: 0x3000, 0x1dcd: 0x3000, 0x1dce: 0x3000, 0x1dcf: 0x3000, 0x1dd0: 0x3000, 0x1dd1: 0x3000, + 0x1dd2: 0x3000, 0x1dd3: 0x3000, 0x1dd4: 0x3000, 0x1dd5: 0x3000, 0x1dd6: 0x3000, 0x1dd7: 0x3000, + 0x1dd8: 0x3000, 0x1dd9: 0x3000, 0x1dda: 0x3000, 0x1ddb: 0x3000, 0x1ddc: 0x3000, 0x1ddd: 0x3000, + 0x1dde: 0x3000, 0x1ddf: 0x3000, 0x1de0: 0x3000, 0x1de1: 0x3000, 0x1de2: 0x3000, 0x1de3: 0x3000, + 0x1de4: 0x3000, 0x1de5: 0x3000, 0x1de6: 0x3000, 0x1de7: 0x3000, 0x1de8: 0x3000, 0x1de9: 0x3000, + 0x1dea: 0x3000, 0x1deb: 0x3000, 0x1dec: 0x3000, 0x1ded: 0x3000, 0x1dee: 0x3000, 0x1def: 0x3000, + 0x1df0: 0x3000, 0x1df1: 0x3000, 0x1df2: 0x3000, 0x1df3: 0x3000, 0x1df4: 0x3000, 0x1df5: 0x3000, + 0x1df6: 0x3000, 0x1df7: 0x3000, 0x1df8: 0x3000, 0x1df9: 0x3000, 0x1dfa: 0x3000, 0x1dfb: 0x3000, + 0x1dfc: 0x3000, 0x1dfd: 0x3000, 0x1dfe: 0x3000, + // Block 0x78, offset 0x1e00 + 0x1e2f: 0x00e6, + 0x1e3c: 0x00e6, 0x1e3d: 0x00e6, + // Block 0x79, offset 0x1e40 + 0x1e70: 0x00e6, 0x1e71: 0x00e6, + // Block 0x7a, offset 0x1e80 + 0x1eb0: 0x3000, + // Block 0x7b, offset 0x1ec0 + 0x1ec6: 0x0009, + // Block 0x7c, offset 0x1f00 + 0x1f04: 0x0009, + 0x1f20: 0x00e6, 0x1f21: 0x00e6, 0x1f22: 0x00e6, 0x1f23: 0x00e6, + 0x1f24: 0x00e6, 0x1f25: 0x00e6, 0x1f26: 0x00e6, 0x1f27: 0x00e6, 0x1f28: 0x00e6, 0x1f29: 0x00e6, + 0x1f2a: 0x00e6, 0x1f2b: 0x00e6, 0x1f2c: 0x00e6, 0x1f2d: 0x00e6, 0x1f2e: 0x00e6, 0x1f2f: 0x00e6, + 0x1f30: 0x00e6, 0x1f31: 0x00e6, + // Block 0x7d, offset 0x1f40 + 0x1f6b: 0x00dc, 0x1f6c: 0x00dc, 0x1f6d: 0x00dc, + // Block 0x7e, offset 0x1f80 + 0x1f93: 0x0009, + // Block 0x7f, offset 0x1fc0 + 0x1ff3: 0x0007, + // Block 0x80, offset 0x2000 + 0x2000: 0x0009, + // Block 0x81, offset 0x2040 + 0x2070: 0x00e6, 0x2072: 0x00e6, 0x2073: 0x00e6, 0x2074: 0x00dc, + 0x2077: 0x00e6, 0x2078: 0x00e6, + 0x207e: 0x00e6, 0x207f: 0x00e6, + // Block 0x82, offset 0x2080 + 0x2081: 0x00e6, + // Block 0x83, offset 0x20c0 + 0x20ed: 0x0009, + // Block 0x84, offset 0x2100 + 0x2100: 0x1100, 0x2101: 0x1100, 0x2102: 0x1100, 0x2103: 0x1100, 0x2104: 0x1100, 0x2105: 0x1100, + 0x2106: 0x1100, 0x2107: 0x1100, 0x2108: 0x1100, 0x2109: 0x1100, 0x210a: 0x1100, 0x210b: 0x1100, + 0x210c: 0x1100, 0x210d: 0x1100, 0x210e: 0x1100, 0x210f: 0x1100, 0x2110: 0x1100, 0x2111: 0x1100, + 0x2112: 0x1100, 0x2113: 0x1100, 0x2114: 0x1100, 0x2115: 0x1100, 0x2116: 0x1100, 0x2117: 0x1100, + 0x2118: 0x1100, 0x2119: 0x1100, 0x211a: 0x1100, 0x211b: 0x1100, 0x211c: 0x1100, 0x211d: 0x1100, + 0x211e: 0x1100, 0x211f: 0x1100, 0x2120: 0x1100, 0x2121: 0x1100, 0x2122: 0x1100, 0x2123: 0x1100, + 0x2124: 0x1100, 0x2125: 0x1100, 0x2126: 0x1100, 0x2127: 0x1100, 0x2128: 0x1100, 0x2129: 0x1100, + 0x212a: 0x1100, 0x212b: 0x1100, 0x212c: 0x1100, 0x212d: 0x1100, 0x212e: 0x1100, 0x212f: 0x1100, + 0x2130: 0x1100, 0x2131: 0x1100, 0x2132: 0x1100, 0x2133: 0x1100, 0x2134: 0x1100, 0x2135: 0x1100, + 0x2136: 0x1100, 0x2137: 0x1100, 0x2138: 0x1100, 0x2139: 0x1100, 0x213a: 0x1100, 0x213b: 0x1100, + 0x213c: 0x1100, 0x213d: 0x1100, 0x213e: 0x1100, 0x213f: 0x1100, + // Block 0x85, offset 0x2140 + 0x2140: 0x1100, 0x2141: 0x1100, 0x2142: 0x1100, 0x2143: 0x1100, 0x2144: 0x1100, 0x2145: 0x1100, + 0x2146: 0x1100, 0x2147: 0x1100, 0x2148: 0x1100, 0x2149: 0x1100, 0x214a: 0x1100, 0x214b: 0x1100, + 0x214c: 0x1100, 0x214d: 0x1100, 0x214e: 0x1100, 0x214f: 0x1100, 0x2150: 0x1100, 0x2151: 0x1100, + 0x2152: 0x1100, 0x2153: 0x1100, 0x2154: 0x1100, 0x2155: 0x1100, 0x2156: 0x1100, 0x2157: 0x1100, + 0x2158: 0x1100, 0x2159: 0x1100, 0x215a: 0x1100, 0x215b: 0x1100, 0x215c: 0x1100, 0x215d: 0x1100, + 0x215e: 0x1100, 0x215f: 0x1100, 0x2160: 0x1100, 0x2161: 0x1100, 0x2162: 0x1100, 0x2163: 0x1100, + // Block 0x86, offset 0x2180 + 0x2180: 0x3300, 0x2181: 0x3300, 0x2182: 0x3300, 0x2183: 0x3300, 0x2184: 0x3300, 0x2185: 0x3300, + 0x2186: 0x3300, 0x2187: 0x3300, 0x2188: 0x3300, 0x2189: 0x3300, 0x218a: 0x3300, 0x218b: 0x3300, + 0x218c: 0x3300, 0x218d: 0x3300, 0x218e: 0x3300, 0x218f: 0x3300, 0x2190: 0x3300, 0x2191: 0x3300, + 0x2192: 0x3300, 0x2193: 0x3300, 0x2194: 0x3300, 0x2195: 0x3300, 0x2196: 0x3300, 0x2197: 0x3300, + 0x2198: 0x3300, 0x2199: 0x3300, 0x219a: 0x3300, 0x219b: 0x3300, 0x219c: 0x3300, 0x219d: 0x3300, + 0x219e: 0x3300, 0x219f: 0x3300, 0x21a0: 0x3300, 0x21a1: 0x3300, 0x21a2: 0x3300, 0x21a3: 0x3300, + 0x21a4: 0x3300, 0x21a5: 0x3300, 0x21a6: 0x3300, 0x21a7: 0x3300, 0x21a8: 0x3300, 0x21a9: 0x3300, + 0x21aa: 0x3300, 0x21ab: 0x3300, 0x21ac: 0x3300, 0x21ad: 0x3300, 0x21ae: 0x3300, 0x21af: 0x3300, + 0x21b0: 0x3300, 0x21b1: 0x3300, 0x21b2: 0x3300, 0x21b3: 0x3300, 0x21b4: 0x3300, 0x21b5: 0x3300, + 0x21b6: 0x3300, 0x21b7: 0x3300, 0x21b8: 0x3300, 0x21b9: 0x3300, 0x21ba: 0x3300, 0x21bb: 0x3300, + 0x21bc: 0x3300, 0x21bd: 0x3300, 0x21be: 0x3300, 0x21bf: 0x3300, + // Block 0x87, offset 0x21c0 + 0x21c0: 0x3300, 0x21c1: 0x3300, 0x21c2: 0x3300, 0x21c3: 0x3300, 0x21c4: 0x3300, 0x21c5: 0x3300, + 0x21c6: 0x3300, 0x21c7: 0x3300, 0x21c8: 0x3300, 0x21c9: 0x3300, 0x21ca: 0x3300, 0x21cb: 0x3300, + 0x21cc: 0x3300, 0x21cd: 0x3300, 0x21d0: 0x3300, + 0x21d2: 0x3300, 0x21d5: 0x3300, 0x21d6: 0x3300, 0x21d7: 0x3300, + 0x21d8: 0x3300, 0x21d9: 0x3300, 0x21da: 0x3300, 0x21db: 0x3300, 0x21dc: 0x3300, 0x21dd: 0x3300, + 0x21de: 0x3300, 0x21e0: 0x3300, 0x21e2: 0x3300, + 0x21e5: 0x3300, 0x21e6: 0x3300, + 0x21ea: 0x3300, 0x21eb: 0x3300, 0x21ec: 0x3300, 0x21ed: 0x3300, + 0x21f0: 0x3300, 0x21f1: 0x3300, 0x21f2: 0x3300, 0x21f3: 0x3300, 0x21f4: 0x3300, 0x21f5: 0x3300, + 0x21f6: 0x3300, 0x21f7: 0x3300, 0x21f8: 0x3300, 0x21f9: 0x3300, 0x21fa: 0x3300, 0x21fb: 0x3300, + 0x21fc: 0x3300, 0x21fd: 0x3300, 0x21fe: 0x3300, 0x21ff: 0x3300, + // Block 0x88, offset 0x2200 + 0x2200: 0x3300, 0x2201: 0x3300, 0x2202: 0x3300, 0x2203: 0x3300, 0x2204: 0x3300, 0x2205: 0x3300, + 0x2206: 0x3300, 0x2207: 0x3300, 0x2208: 0x3300, 0x2209: 0x3300, 0x220a: 0x3300, 0x220b: 0x3300, + 0x220c: 0x3300, 0x220d: 0x3300, 0x220e: 0x3300, 0x220f: 0x3300, 0x2210: 0x3300, 0x2211: 0x3300, + 0x2212: 0x3300, 0x2213: 0x3300, 0x2214: 0x3300, 0x2215: 0x3300, 0x2216: 0x3300, 0x2217: 0x3300, + 0x2218: 0x3300, 0x2219: 0x3300, 0x221a: 0x3300, 0x221b: 0x3300, 0x221c: 0x3300, 0x221d: 0x3300, + 0x221e: 0x3300, 0x221f: 0x3300, 0x2220: 0x3300, 0x2221: 0x3300, 0x2222: 0x3300, 0x2223: 0x3300, + 0x2224: 0x3300, 0x2225: 0x3300, 0x2226: 0x3300, 0x2227: 0x3300, 0x2228: 0x3300, 0x2229: 0x3300, + 0x222a: 0x3300, 0x222b: 0x3300, 0x222c: 0x3300, 0x222d: 0x3300, + 0x2230: 0x3300, 0x2231: 0x3300, 0x2232: 0x3300, 0x2233: 0x3300, 0x2234: 0x3300, 0x2235: 0x3300, + 0x2236: 0x3300, 0x2237: 0x3300, 0x2238: 0x3300, 0x2239: 0x3300, 0x223a: 0x3300, 0x223b: 0x3300, + 0x223c: 0x3300, 0x223d: 0x3300, 0x223e: 0x3300, 0x223f: 0x3300, + // Block 0x89, offset 0x2240 + 0x2240: 0x3300, 0x2241: 0x3300, 0x2242: 0x3300, 0x2243: 0x3300, 0x2244: 0x3300, 0x2245: 0x3300, + 0x2246: 0x3300, 0x2247: 0x3300, 0x2248: 0x3300, 0x2249: 0x3300, 0x224a: 0x3300, 0x224b: 0x3300, + 0x224c: 0x3300, 0x224d: 0x3300, 0x224e: 0x3300, 0x224f: 0x3300, 0x2250: 0x3300, 0x2251: 0x3300, + 0x2252: 0x3300, 0x2253: 0x3300, 0x2254: 0x3300, 0x2255: 0x3300, 0x2256: 0x3300, 0x2257: 0x3300, + 0x2258: 0x3300, 0x2259: 0x3300, + // Block 0x8a, offset 0x2280 + 0x2280: 0x3000, 0x2281: 0x3000, 0x2282: 0x3000, 0x2283: 0x3000, 0x2284: 0x3000, 0x2285: 0x3000, + 0x2286: 0x3000, + 0x2293: 0x3000, 0x2294: 0x3000, 0x2295: 0x3000, 0x2296: 0x3000, 0x2297: 0x3000, + 0x229d: 0x3300, + 0x229e: 0x001a, 0x229f: 0x3300, 0x22a0: 0x3000, 0x22a1: 0x3000, 0x22a2: 0x3000, 0x22a3: 0x3000, + 0x22a4: 0x3000, 0x22a5: 0x3000, 0x22a6: 0x3000, 0x22a7: 0x3000, 0x22a8: 0x3000, 0x22a9: 0x3000, + 0x22aa: 0x3300, 0x22ab: 0x3300, 0x22ac: 0x3300, 0x22ad: 0x3300, 0x22ae: 0x3300, 0x22af: 0x3300, + 0x22b0: 0x3300, 0x22b1: 0x3300, 0x22b2: 0x3300, 0x22b3: 0x3300, 0x22b4: 0x3300, 0x22b5: 0x3300, + 0x22b6: 0x3300, 0x22b8: 0x3300, 0x22b9: 0x3300, 0x22ba: 0x3300, 0x22bb: 0x3300, + 0x22bc: 0x3300, 0x22be: 0x3300, + // Block 0x8b, offset 0x22c0 + 0x22c0: 0x3300, 0x22c1: 0x3300, 0x22c3: 0x3300, 0x22c4: 0x3300, + 0x22c6: 0x3300, 0x22c7: 0x3300, 0x22c8: 0x3300, 0x22c9: 0x3300, 0x22ca: 0x3300, 0x22cb: 0x3300, + 0x22cc: 0x3300, 0x22cd: 0x3300, 0x22ce: 0x3300, 0x22cf: 0x3000, 0x22d0: 0x3000, 0x22d1: 0x3000, + 0x22d2: 0x3000, 0x22d3: 0x3000, 0x22d4: 0x3000, 0x22d5: 0x3000, 0x22d6: 0x3000, 0x22d7: 0x3000, + 0x22d8: 0x3000, 0x22d9: 0x3000, 0x22da: 0x3000, 0x22db: 0x3000, 0x22dc: 0x3000, 0x22dd: 0x3000, + 0x22de: 0x3000, 0x22df: 0x3000, 0x22e0: 0x3000, 0x22e1: 0x3000, 0x22e2: 0x3000, 0x22e3: 0x3000, + 0x22e4: 0x3000, 0x22e5: 0x3000, 0x22e6: 0x3000, 0x22e7: 0x3000, 0x22e8: 0x3000, 0x22e9: 0x3000, + 0x22ea: 0x3000, 0x22eb: 0x3000, 0x22ec: 0x3000, 0x22ed: 0x3000, 0x22ee: 0x3000, 0x22ef: 0x3000, + 0x22f0: 0x3000, 0x22f1: 0x3000, 0x22f2: 0x3000, 0x22f3: 0x3000, 0x22f4: 0x3000, 0x22f5: 0x3000, + 0x22f6: 0x3000, 0x22f7: 0x3000, 0x22f8: 0x3000, 0x22f9: 0x3000, 0x22fa: 0x3000, 0x22fb: 0x3000, + 0x22fc: 0x3000, 0x22fd: 0x3000, 0x22fe: 0x3000, 0x22ff: 0x3000, + // Block 0x8c, offset 0x2300 + 0x2300: 0x3000, 0x2301: 0x3000, 0x2302: 0x3000, 0x2303: 0x3000, 0x2304: 0x3000, 0x2305: 0x3000, + 0x2306: 0x3000, 0x2307: 0x3000, 0x2308: 0x3000, 0x2309: 0x3000, 0x230a: 0x3000, 0x230b: 0x3000, + 0x230c: 0x3000, 0x230d: 0x3000, 0x230e: 0x3000, 0x230f: 0x3000, 0x2310: 0x3000, 0x2311: 0x3000, + 0x2312: 0x3000, 0x2313: 0x3000, 0x2314: 0x3000, 0x2315: 0x3000, 0x2316: 0x3000, 0x2317: 0x3000, + 0x2318: 0x3000, 0x2319: 0x3000, 0x231a: 0x3000, 0x231b: 0x3000, 0x231c: 0x3000, 0x231d: 0x3000, + 0x231e: 0x3000, 0x231f: 0x3000, 0x2320: 0x3000, 0x2321: 0x3000, 0x2322: 0x3000, 0x2323: 0x3000, + 0x2324: 0x3000, 0x2325: 0x3000, 0x2326: 0x3000, 0x2327: 0x3000, 0x2328: 0x3000, 0x2329: 0x3000, + 0x232a: 0x3000, 0x232b: 0x3000, 0x232c: 0x3000, 0x232d: 0x3000, 0x232e: 0x3000, 0x232f: 0x3000, + 0x2330: 0x3000, 0x2331: 0x3000, + // Block 0x8d, offset 0x2340 + 0x2353: 0x3000, 0x2354: 0x3000, 0x2355: 0x3000, 0x2356: 0x3000, 0x2357: 0x3000, + 0x2358: 0x3000, 0x2359: 0x3000, 0x235a: 0x3000, 0x235b: 0x3000, 0x235c: 0x3000, 0x235d: 0x3000, + 0x235e: 0x3000, 0x235f: 0x3000, 0x2360: 0x3000, 0x2361: 0x3000, 0x2362: 0x3000, 0x2363: 0x3000, + 0x2364: 0x3000, 0x2365: 0x3000, 0x2366: 0x3000, 0x2367: 0x3000, 0x2368: 0x3000, 0x2369: 0x3000, + 0x236a: 0x3000, 0x236b: 0x3000, 0x236c: 0x3000, 0x236d: 0x3000, 0x236e: 0x3000, 0x236f: 0x3000, + 0x2370: 0x3000, 0x2371: 0x3000, 0x2372: 0x3000, 0x2373: 0x3000, 0x2374: 0x3000, 0x2375: 0x3000, + 0x2376: 0x3000, 0x2377: 0x3000, 0x2378: 0x3000, 0x2379: 0x3000, 0x237a: 0x3000, 0x237b: 0x3000, + 0x237c: 0x3000, 0x237d: 0x3000, 0x237e: 0x3000, 0x237f: 0x3000, + // Block 0x8e, offset 0x2380 + 0x2380: 0x3000, 0x2381: 0x3000, 0x2382: 0x3000, 0x2383: 0x3000, 0x2384: 0x3000, 0x2385: 0x3000, + 0x2386: 0x3000, 0x2387: 0x3000, 0x2388: 0x3000, 0x2389: 0x3000, 0x238a: 0x3000, 0x238b: 0x3000, + 0x238c: 0x3000, 0x238d: 0x3000, 0x238e: 0x3000, 0x238f: 0x3000, 0x2390: 0x3000, 0x2391: 0x3000, + 0x2392: 0x3000, 0x2393: 0x3000, 0x2394: 0x3000, 0x2395: 0x3000, 0x2396: 0x3000, 0x2397: 0x3000, + 0x2398: 0x3000, 0x2399: 0x3000, 0x239a: 0x3000, 0x239b: 0x3000, 0x239c: 0x3000, 0x239d: 0x3000, + 0x239e: 0x3000, 0x239f: 0x3000, 0x23a0: 0x3000, 0x23a1: 0x3000, 0x23a2: 0x3000, 0x23a3: 0x3000, + 0x23a4: 0x3000, 0x23a5: 0x3000, 0x23a6: 0x3000, 0x23a7: 0x3000, 0x23a8: 0x3000, 0x23a9: 0x3000, + 0x23aa: 0x3000, 0x23ab: 0x3000, 0x23ac: 0x3000, 0x23ad: 0x3000, 0x23ae: 0x3000, 0x23af: 0x3000, + 0x23b0: 0x3000, 0x23b1: 0x3000, 0x23b2: 0x3000, 0x23b3: 0x3000, 0x23b4: 0x3000, 0x23b5: 0x3000, + 0x23b6: 0x3000, 0x23b7: 0x3000, 0x23b8: 0x3000, 0x23b9: 0x3000, 0x23ba: 0x3000, 0x23bb: 0x3000, + 0x23bc: 0x3000, 0x23bd: 0x3000, + // Block 0x8f, offset 0x23c0 + 0x23d0: 0x3000, 0x23d1: 0x3000, + 0x23d2: 0x3000, 0x23d3: 0x3000, 0x23d4: 0x3000, 0x23d5: 0x3000, 0x23d6: 0x3000, 0x23d7: 0x3000, + 0x23d8: 0x3000, 0x23d9: 0x3000, 0x23da: 0x3000, 0x23db: 0x3000, 0x23dc: 0x3000, 0x23dd: 0x3000, + 0x23de: 0x3000, 0x23df: 0x3000, 0x23e0: 0x3000, 0x23e1: 0x3000, 0x23e2: 0x3000, 0x23e3: 0x3000, + 0x23e4: 0x3000, 0x23e5: 0x3000, 0x23e6: 0x3000, 0x23e7: 0x3000, 0x23e8: 0x3000, 0x23e9: 0x3000, + 0x23ea: 0x3000, 0x23eb: 0x3000, 0x23ec: 0x3000, 0x23ed: 0x3000, 0x23ee: 0x3000, 0x23ef: 0x3000, + 0x23f0: 0x3000, 0x23f1: 0x3000, 0x23f2: 0x3000, 0x23f3: 0x3000, 0x23f4: 0x3000, 0x23f5: 0x3000, + 0x23f6: 0x3000, 0x23f7: 0x3000, 0x23f8: 0x3000, 0x23f9: 0x3000, 0x23fa: 0x3000, 0x23fb: 0x3000, + 0x23fc: 0x3000, 0x23fd: 0x3000, 0x23fe: 0x3000, 0x23ff: 0x3000, + // Block 0x90, offset 0x2400 + 0x2400: 0x3000, 0x2401: 0x3000, 0x2402: 0x3000, 0x2403: 0x3000, 0x2404: 0x3000, 0x2405: 0x3000, + 0x2406: 0x3000, 0x2407: 0x3000, 0x2408: 0x3000, 0x2409: 0x3000, 0x240a: 0x3000, 0x240b: 0x3000, + 0x240c: 0x3000, 0x240d: 0x3000, 0x240e: 0x3000, 0x240f: 0x3000, + 0x2412: 0x3000, 0x2413: 0x3000, 0x2414: 0x3000, 0x2415: 0x3000, 0x2416: 0x3000, 0x2417: 0x3000, + 0x2418: 0x3000, 0x2419: 0x3000, 0x241a: 0x3000, 0x241b: 0x3000, 0x241c: 0x3000, 0x241d: 0x3000, + 0x241e: 0x3000, 0x241f: 0x3000, 0x2420: 0x3000, 0x2421: 0x3000, 0x2422: 0x3000, 0x2423: 0x3000, + 0x2424: 0x3000, 0x2425: 0x3000, 0x2426: 0x3000, 0x2427: 0x3000, 0x2428: 0x3000, 0x2429: 0x3000, + 0x242a: 0x3000, 0x242b: 0x3000, 0x242c: 0x3000, 0x242d: 0x3000, 0x242e: 0x3000, 0x242f: 0x3000, + 0x2430: 0x3000, 0x2431: 0x3000, 0x2432: 0x3000, 0x2433: 0x3000, 0x2434: 0x3000, 0x2435: 0x3000, + 0x2436: 0x3000, 0x2437: 0x3000, 0x2438: 0x3000, 0x2439: 0x3000, 0x243a: 0x3000, 0x243b: 0x3000, + 0x243c: 0x3000, 0x243d: 0x3000, 0x243e: 0x3000, 0x243f: 0x3000, + // Block 0x91, offset 0x2440 + 0x2440: 0x3000, 0x2441: 0x3000, 0x2442: 0x3000, 0x2443: 0x3000, 0x2444: 0x3000, 0x2445: 0x3000, + 0x2446: 0x3000, 0x2447: 0x3000, + 0x2470: 0x3000, 0x2471: 0x3000, 0x2472: 0x3000, 0x2473: 0x3000, 0x2474: 0x3000, 0x2475: 0x3000, + 0x2476: 0x3000, 0x2477: 0x3000, 0x2478: 0x3000, 0x2479: 0x3000, 0x247a: 0x3000, 0x247b: 0x3000, + 0x247c: 0x3000, + // Block 0x92, offset 0x2480 + 0x2490: 0x3000, 0x2491: 0x3000, + 0x2492: 0x3000, 0x2493: 0x3000, 0x2494: 0x3000, 0x2495: 0x3000, 0x2496: 0x3000, 0x2497: 0x3000, + 0x2498: 0x3000, 0x2499: 0x3000, + 0x24a0: 0x00e6, 0x24a1: 0x00e6, 0x24a2: 0x00e6, 0x24a3: 0x00e6, + 0x24a4: 0x00e6, 0x24a5: 0x00e6, 0x24a6: 0x00e6, + 0x24b0: 0x3000, 0x24b1: 0x3000, 0x24b2: 0x3000, 0x24b3: 0x3000, 0x24b4: 0x3000, 0x24b5: 0x3000, + 0x24b6: 0x3000, 0x24b7: 0x3000, 0x24b8: 0x3000, 0x24b9: 0x3000, 0x24ba: 0x3000, 0x24bb: 0x3000, + 0x24bc: 0x3000, 0x24bd: 0x3000, 0x24be: 0x3000, 0x24bf: 0x3000, + // Block 0x93, offset 0x24c0 + 0x24c0: 0x3000, 0x24c1: 0x3000, 0x24c2: 0x3000, 0x24c3: 0x3000, 0x24c4: 0x3000, + 0x24c7: 0x3000, 0x24c8: 0x3000, 0x24c9: 0x3000, 0x24ca: 0x3000, 0x24cb: 0x3000, + 0x24cc: 0x3000, 0x24cd: 0x3000, 0x24ce: 0x3000, 0x24cf: 0x3000, 0x24d0: 0x3000, 0x24d1: 0x3000, + 0x24d2: 0x3000, 0x24d4: 0x3000, 0x24d5: 0x3000, 0x24d6: 0x3000, 0x24d7: 0x3000, + 0x24d8: 0x3000, 0x24d9: 0x3000, 0x24da: 0x3000, 0x24db: 0x3000, 0x24dc: 0x3000, 0x24dd: 0x3000, + 0x24de: 0x3000, 0x24df: 0x3000, 0x24e0: 0x3000, 0x24e1: 0x3000, 0x24e2: 0x3000, 0x24e3: 0x3000, + 0x24e4: 0x3000, 0x24e5: 0x3000, 0x24e6: 0x3000, 0x24e8: 0x3000, 0x24e9: 0x3000, + 0x24ea: 0x3000, 0x24eb: 0x3000, + 0x24f0: 0x3000, 0x24f1: 0x3000, 0x24f2: 0x3000, 0x24f4: 0x3000, + 0x24f6: 0x3000, 0x24f7: 0x3000, 0x24f8: 0x3000, 0x24f9: 0x3000, 0x24fa: 0x3000, 0x24fb: 0x3000, + 0x24fc: 0x3000, 0x24fd: 0x3000, 0x24fe: 0x3000, 0x24ff: 0x3000, + // Block 0x94, offset 0x2500 + 0x2500: 0x3000, 0x2501: 0x3000, 0x2502: 0x3000, 0x2503: 0x3000, 0x2504: 0x3000, 0x2505: 0x3000, + 0x2506: 0x3000, 0x2507: 0x3000, 0x2508: 0x3000, 0x2509: 0x3000, 0x250a: 0x3000, 0x250b: 0x3000, + 0x250c: 0x3000, 0x250d: 0x3000, 0x250e: 0x3000, 0x250f: 0x3000, 0x2510: 0x3000, 0x2511: 0x3000, + 0x2512: 0x3000, 0x2513: 0x3000, 0x2514: 0x3000, 0x2515: 0x3000, 0x2516: 0x3000, 0x2517: 0x3000, + 0x2518: 0x3000, 0x2519: 0x3000, 0x251a: 0x3000, 0x251b: 0x3000, 0x251c: 0x3000, 0x251d: 0x3000, + 0x251e: 0x3000, 0x251f: 0x3000, 0x2520: 0x3000, 0x2521: 0x3000, 0x2522: 0x3000, 0x2523: 0x3000, + 0x2524: 0x3000, 0x2525: 0x3000, 0x2526: 0x3000, 0x2527: 0x3000, 0x2528: 0x3000, 0x2529: 0x3000, + 0x252a: 0x3000, 0x252b: 0x3000, 0x252c: 0x3000, 0x252d: 0x3000, 0x252e: 0x3000, 0x252f: 0x3000, + 0x2530: 0x3000, 0x2531: 0x3000, 0x2532: 0x3000, 0x2533: 0x3000, 0x2534: 0x3000, 0x2535: 0x3000, + 0x2536: 0x3000, 0x2537: 0x3000, 0x2538: 0x3000, 0x2539: 0x3000, 0x253a: 0x3000, 0x253b: 0x3000, + 0x253c: 0x3000, + // Block 0x95, offset 0x2540 + 0x2541: 0x3000, 0x2542: 0x3000, 0x2543: 0x3000, 0x2544: 0x3000, 0x2545: 0x3000, + 0x2546: 0x3000, 0x2547: 0x3000, 0x2548: 0x3000, 0x2549: 0x3000, 0x254a: 0x3000, 0x254b: 0x3000, + 0x254c: 0x3000, 0x254d: 0x3000, 0x254e: 0x3000, 0x254f: 0x3000, 0x2550: 0x3000, 0x2551: 0x3000, + 0x2552: 0x3000, 0x2553: 0x3000, 0x2554: 0x3000, 0x2555: 0x3000, 0x2556: 0x3000, 0x2557: 0x3000, + 0x2558: 0x3000, 0x2559: 0x3000, 0x255a: 0x3000, 0x255b: 0x3000, 0x255c: 0x3000, 0x255d: 0x3000, + 0x255e: 0x3000, 0x255f: 0x3000, 0x2560: 0x3000, 0x2561: 0x3000, 0x2562: 0x3000, 0x2563: 0x3000, + 0x2564: 0x3000, 0x2565: 0x3000, 0x2566: 0x3000, 0x2567: 0x3000, 0x2568: 0x3000, 0x2569: 0x3000, + 0x256a: 0x3000, 0x256b: 0x3000, 0x256c: 0x3000, 0x256d: 0x3000, 0x256e: 0x3000, 0x256f: 0x3000, + 0x2570: 0x3000, 0x2571: 0x3000, 0x2572: 0x3000, 0x2573: 0x3000, 0x2574: 0x3000, 0x2575: 0x3000, + 0x2576: 0x3000, 0x2577: 0x3000, 0x2578: 0x3000, 0x2579: 0x3000, 0x257a: 0x3000, 0x257b: 0x3000, + 0x257c: 0x3000, 0x257d: 0x3000, 0x257e: 0x3000, 0x257f: 0x3000, + // Block 0x96, offset 0x2580 + 0x2582: 0x3000, 0x2583: 0x3000, 0x2584: 0x3000, 0x2585: 0x3000, + 0x2586: 0x3000, 0x2587: 0x3000, 0x258a: 0x3000, 0x258b: 0x3000, + 0x258c: 0x3000, 0x258d: 0x3000, 0x258e: 0x3000, 0x258f: 0x3000, + 0x2592: 0x3000, 0x2593: 0x3000, 0x2594: 0x3000, 0x2595: 0x3000, 0x2596: 0x3000, 0x2597: 0x3000, + 0x259a: 0x3000, 0x259b: 0x3000, 0x259c: 0x3000, + 0x25a0: 0x3000, 0x25a1: 0x3000, 0x25a2: 0x3000, 0x25a3: 0x3000, + 0x25a4: 0x3000, 0x25a5: 0x3000, 0x25a6: 0x3000, 0x25a8: 0x3000, 0x25a9: 0x3000, + 0x25aa: 0x3000, 0x25ab: 0x3000, 0x25ac: 0x3000, 0x25ad: 0x3000, 0x25ae: 0x3000, + // Block 0x97, offset 0x25c0 + 0x25fd: 0x00dc, + // Block 0x98, offset 0x2600 + 0x260d: 0x00dc, 0x260f: 0x00e6, + 0x2638: 0x00e6, 0x2639: 0x0001, 0x263a: 0x00dc, + 0x263f: 0x0009, + // Block 0x99, offset 0x2640 + 0x2659: 0x8800, 0x265a: 0x1100, 0x265b: 0x8800, 0x265c: 0x1100, + 0x2665: 0x8800, + 0x266b: 0x1100, + 0x2679: 0x0009, 0x267a: 0x6607, + // Block 0x9a, offset 0x2680 + 0x269e: 0x3300, 0x269f: 0x3300, 0x26a0: 0x3300, 0x26a1: 0x3300, 0x26a2: 0x3300, 0x26a3: 0x3300, + 0x26a4: 0x3300, 0x26a5: 0x00d8, 0x26a6: 0x00d8, 0x26a7: 0x0001, 0x26a8: 0x0001, 0x26a9: 0x0001, + 0x26ad: 0x00e2, 0x26ae: 0x00d8, 0x26af: 0x00d8, + 0x26b0: 0x00d8, 0x26b1: 0x00d8, 0x26b2: 0x00d8, + 0x26bb: 0x00dc, + 0x26bc: 0x00dc, 0x26bd: 0x00dc, 0x26be: 0x00dc, 0x26bf: 0x00dc, + // Block 0x9b, offset 0x26c0 + 0x26c0: 0x00dc, 0x26c1: 0x00dc, 0x26c2: 0x00dc, 0x26c5: 0x00e6, + 0x26c6: 0x00e6, 0x26c7: 0x00e6, 0x26c8: 0x00e6, 0x26c9: 0x00e6, 0x26ca: 0x00dc, 0x26cb: 0x00dc, + 0x26ea: 0x00e6, 0x26eb: 0x00e6, 0x26ec: 0x00e6, 0x26ed: 0x00e6, + 0x26fb: 0x3300, + 0x26fc: 0x3300, 0x26fd: 0x3300, 0x26fe: 0x3300, 0x26ff: 0x3300, + // Block 0x9c, offset 0x2700 + 0x2700: 0x3300, + // Block 0x9d, offset 0x2740 + 0x2742: 0x00e6, 0x2743: 0x00e6, 0x2744: 0x00e6, + // Block 0x9e, offset 0x2780 + 0x2780: 0x3000, 0x2781: 0x3000, 0x2782: 0x3000, 0x2783: 0x3000, 0x2784: 0x3000, 0x2785: 0x3000, + 0x2786: 0x3000, 0x2787: 0x3000, 0x2788: 0x3000, 0x2789: 0x3000, 0x278a: 0x3000, 0x278b: 0x3000, + 0x278c: 0x3000, 0x278d: 0x3000, 0x278e: 0x3000, 0x278f: 0x3000, 0x2790: 0x3000, 0x2791: 0x3000, + 0x2792: 0x3000, 0x2793: 0x3000, 0x2794: 0x3000, 0x2796: 0x3000, 0x2797: 0x3000, + 0x2798: 0x3000, 0x2799: 0x3000, 0x279a: 0x3000, 0x279b: 0x3000, 0x279c: 0x3000, 0x279d: 0x3000, + 0x279e: 0x3000, 0x279f: 0x3000, 0x27a0: 0x3000, 0x27a1: 0x3000, 0x27a2: 0x3000, 0x27a3: 0x3000, + 0x27a4: 0x3000, 0x27a5: 0x3000, 0x27a6: 0x3000, 0x27a7: 0x3000, 0x27a8: 0x3000, 0x27a9: 0x3000, + 0x27aa: 0x3000, 0x27ab: 0x3000, 0x27ac: 0x3000, 0x27ad: 0x3000, 0x27ae: 0x3000, 0x27af: 0x3000, + 0x27b0: 0x3000, 0x27b1: 0x3000, 0x27b2: 0x3000, 0x27b3: 0x3000, 0x27b4: 0x3000, 0x27b5: 0x3000, + 0x27b6: 0x3000, 0x27b7: 0x3000, 0x27b8: 0x3000, 0x27b9: 0x3000, 0x27ba: 0x3000, 0x27bb: 0x3000, + 0x27bc: 0x3000, 0x27bd: 0x3000, 0x27be: 0x3000, 0x27bf: 0x3000, + // Block 0x9f, offset 0x27c0 + 0x27c0: 0x3000, 0x27c1: 0x3000, 0x27c2: 0x3000, 0x27c3: 0x3000, 0x27c4: 0x3000, 0x27c5: 0x3000, + 0x27c6: 0x3000, 0x27c7: 0x3000, 0x27c8: 0x3000, 0x27c9: 0x3000, 0x27ca: 0x3000, 0x27cb: 0x3000, + 0x27cc: 0x3000, 0x27cd: 0x3000, 0x27ce: 0x3000, 0x27cf: 0x3000, 0x27d0: 0x3000, 0x27d1: 0x3000, + 0x27d2: 0x3000, 0x27d3: 0x3000, 0x27d4: 0x3000, 0x27d5: 0x3000, 0x27d6: 0x3000, 0x27d7: 0x3000, + 0x27d8: 0x3000, 0x27d9: 0x3000, 0x27da: 0x3000, 0x27db: 0x3000, 0x27dc: 0x3000, + 0x27de: 0x3000, 0x27df: 0x3000, 0x27e2: 0x3000, + 0x27e5: 0x3000, 0x27e6: 0x3000, 0x27e9: 0x3000, + 0x27ea: 0x3000, 0x27eb: 0x3000, 0x27ec: 0x3000, 0x27ee: 0x3000, 0x27ef: 0x3000, + 0x27f0: 0x3000, 0x27f1: 0x3000, 0x27f2: 0x3000, 0x27f3: 0x3000, 0x27f4: 0x3000, 0x27f5: 0x3000, + 0x27f6: 0x3000, 0x27f7: 0x3000, 0x27f8: 0x3000, 0x27f9: 0x3000, 0x27fb: 0x3000, + 0x27fd: 0x3000, 0x27fe: 0x3000, 0x27ff: 0x3000, + // Block 0xa0, offset 0x2800 + 0x2800: 0x3000, 0x2801: 0x3000, 0x2802: 0x3000, 0x2803: 0x3000, 0x2805: 0x3000, + 0x2806: 0x3000, 0x2807: 0x3000, 0x2808: 0x3000, 0x2809: 0x3000, 0x280a: 0x3000, 0x280b: 0x3000, + 0x280c: 0x3000, 0x280d: 0x3000, 0x280e: 0x3000, 0x280f: 0x3000, 0x2810: 0x3000, 0x2811: 0x3000, + 0x2812: 0x3000, 0x2813: 0x3000, 0x2814: 0x3000, 0x2815: 0x3000, 0x2816: 0x3000, 0x2817: 0x3000, + 0x2818: 0x3000, 0x2819: 0x3000, 0x281a: 0x3000, 0x281b: 0x3000, 0x281c: 0x3000, 0x281d: 0x3000, + 0x281e: 0x3000, 0x281f: 0x3000, 0x2820: 0x3000, 0x2821: 0x3000, 0x2822: 0x3000, 0x2823: 0x3000, + 0x2824: 0x3000, 0x2825: 0x3000, 0x2826: 0x3000, 0x2827: 0x3000, 0x2828: 0x3000, 0x2829: 0x3000, + 0x282a: 0x3000, 0x282b: 0x3000, 0x282c: 0x3000, 0x282d: 0x3000, 0x282e: 0x3000, 0x282f: 0x3000, + 0x2830: 0x3000, 0x2831: 0x3000, 0x2832: 0x3000, 0x2833: 0x3000, 0x2834: 0x3000, 0x2835: 0x3000, + 0x2836: 0x3000, 0x2837: 0x3000, 0x2838: 0x3000, 0x2839: 0x3000, 0x283a: 0x3000, 0x283b: 0x3000, + 0x283c: 0x3000, 0x283d: 0x3000, 0x283e: 0x3000, 0x283f: 0x3000, + // Block 0xa1, offset 0x2840 + 0x2840: 0x3000, 0x2841: 0x3000, 0x2842: 0x3000, 0x2843: 0x3000, 0x2844: 0x3000, 0x2845: 0x3000, + 0x2847: 0x3000, 0x2848: 0x3000, 0x2849: 0x3000, 0x284a: 0x3000, + 0x284d: 0x3000, 0x284e: 0x3000, 0x284f: 0x3000, 0x2850: 0x3000, 0x2851: 0x3000, + 0x2852: 0x3000, 0x2853: 0x3000, 0x2854: 0x3000, 0x2856: 0x3000, 0x2857: 0x3000, + 0x2858: 0x3000, 0x2859: 0x3000, 0x285a: 0x3000, 0x285b: 0x3000, 0x285c: 0x3000, + 0x285e: 0x3000, 0x285f: 0x3000, 0x2860: 0x3000, 0x2861: 0x3000, 0x2862: 0x3000, 0x2863: 0x3000, + 0x2864: 0x3000, 0x2865: 0x3000, 0x2866: 0x3000, 0x2867: 0x3000, 0x2868: 0x3000, 0x2869: 0x3000, + 0x286a: 0x3000, 0x286b: 0x3000, 0x286c: 0x3000, 0x286d: 0x3000, 0x286e: 0x3000, 0x286f: 0x3000, + 0x2870: 0x3000, 0x2871: 0x3000, 0x2872: 0x3000, 0x2873: 0x3000, 0x2874: 0x3000, 0x2875: 0x3000, + 0x2876: 0x3000, 0x2877: 0x3000, 0x2878: 0x3000, 0x2879: 0x3000, 0x287b: 0x3000, + 0x287c: 0x3000, 0x287d: 0x3000, 0x287e: 0x3000, + // Block 0xa2, offset 0x2880 + 0x2880: 0x3000, 0x2881: 0x3000, 0x2882: 0x3000, 0x2883: 0x3000, 0x2884: 0x3000, + 0x2886: 0x3000, 0x288a: 0x3000, 0x288b: 0x3000, + 0x288c: 0x3000, 0x288d: 0x3000, 0x288e: 0x3000, 0x288f: 0x3000, 0x2890: 0x3000, + 0x2892: 0x3000, 0x2893: 0x3000, 0x2894: 0x3000, 0x2895: 0x3000, 0x2896: 0x3000, 0x2897: 0x3000, + 0x2898: 0x3000, 0x2899: 0x3000, 0x289a: 0x3000, 0x289b: 0x3000, 0x289c: 0x3000, 0x289d: 0x3000, + 0x289e: 0x3000, 0x289f: 0x3000, 0x28a0: 0x3000, 0x28a1: 0x3000, 0x28a2: 0x3000, 0x28a3: 0x3000, + 0x28a4: 0x3000, 0x28a5: 0x3000, 0x28a6: 0x3000, 0x28a7: 0x3000, 0x28a8: 0x3000, 0x28a9: 0x3000, + 0x28aa: 0x3000, 0x28ab: 0x3000, 0x28ac: 0x3000, 0x28ad: 0x3000, 0x28ae: 0x3000, 0x28af: 0x3000, + 0x28b0: 0x3000, 0x28b1: 0x3000, 0x28b2: 0x3000, 0x28b3: 0x3000, 0x28b4: 0x3000, 0x28b5: 0x3000, + 0x28b6: 0x3000, 0x28b7: 0x3000, 0x28b8: 0x3000, 0x28b9: 0x3000, 0x28ba: 0x3000, 0x28bb: 0x3000, + 0x28bc: 0x3000, 0x28bd: 0x3000, 0x28be: 0x3000, 0x28bf: 0x3000, + // Block 0xa3, offset 0x28c0 + 0x28c0: 0x3000, 0x28c1: 0x3000, 0x28c2: 0x3000, 0x28c3: 0x3000, 0x28c4: 0x3000, 0x28c5: 0x3000, + 0x28c6: 0x3000, 0x28c7: 0x3000, 0x28c8: 0x3000, 0x28c9: 0x3000, 0x28ca: 0x3000, 0x28cb: 0x3000, + 0x28cc: 0x3000, 0x28cd: 0x3000, 0x28ce: 0x3000, 0x28cf: 0x3000, 0x28d0: 0x3000, 0x28d1: 0x3000, + 0x28d2: 0x3000, 0x28d3: 0x3000, 0x28d4: 0x3000, 0x28d5: 0x3000, 0x28d6: 0x3000, 0x28d7: 0x3000, + 0x28d8: 0x3000, 0x28d9: 0x3000, 0x28da: 0x3000, 0x28db: 0x3000, 0x28dc: 0x3000, 0x28dd: 0x3000, + 0x28de: 0x3000, 0x28df: 0x3000, 0x28e0: 0x3000, 0x28e1: 0x3000, 0x28e2: 0x3000, 0x28e3: 0x3000, + 0x28e4: 0x3000, 0x28e5: 0x3000, 0x28e8: 0x3000, 0x28e9: 0x3000, + 0x28ea: 0x3000, 0x28eb: 0x3000, 0x28ec: 0x3000, 0x28ed: 0x3000, 0x28ee: 0x3000, 0x28ef: 0x3000, + 0x28f0: 0x3000, 0x28f1: 0x3000, 0x28f2: 0x3000, 0x28f3: 0x3000, 0x28f4: 0x3000, 0x28f5: 0x3000, + 0x28f6: 0x3000, 0x28f7: 0x3000, 0x28f8: 0x3000, 0x28f9: 0x3000, 0x28fa: 0x3000, 0x28fb: 0x3000, + 0x28fc: 0x3000, 0x28fd: 0x3000, 0x28fe: 0x3000, 0x28ff: 0x3000, + // Block 0xa4, offset 0x2900 + 0x2900: 0x3000, 0x2901: 0x3000, 0x2902: 0x3000, 0x2903: 0x3000, 0x2904: 0x3000, 0x2905: 0x3000, + 0x2906: 0x3000, 0x2907: 0x3000, 0x2908: 0x3000, 0x2909: 0x3000, 0x290a: 0x3000, 0x290b: 0x3000, + 0x290e: 0x3000, 0x290f: 0x3000, 0x2910: 0x3000, 0x2911: 0x3000, + 0x2912: 0x3000, 0x2913: 0x3000, 0x2914: 0x3000, 0x2915: 0x3000, 0x2916: 0x3000, 0x2917: 0x3000, + 0x2918: 0x3000, 0x2919: 0x3000, 0x291a: 0x3000, 0x291b: 0x3000, 0x291c: 0x3000, 0x291d: 0x3000, + 0x291e: 0x3000, 0x291f: 0x3000, 0x2920: 0x3000, 0x2921: 0x3000, 0x2922: 0x3000, 0x2923: 0x3000, + 0x2924: 0x3000, 0x2925: 0x3000, 0x2926: 0x3000, 0x2927: 0x3000, 0x2928: 0x3000, 0x2929: 0x3000, + 0x292a: 0x3000, 0x292b: 0x3000, 0x292c: 0x3000, 0x292d: 0x3000, 0x292e: 0x3000, 0x292f: 0x3000, + 0x2930: 0x3000, 0x2931: 0x3000, 0x2932: 0x3000, 0x2933: 0x3000, 0x2934: 0x3000, 0x2935: 0x3000, + 0x2936: 0x3000, 0x2937: 0x3000, 0x2938: 0x3000, 0x2939: 0x3000, 0x293a: 0x3000, 0x293b: 0x3000, + 0x293c: 0x3000, 0x293d: 0x3000, 0x293e: 0x3000, 0x293f: 0x3000, + // Block 0xa5, offset 0x2940 + 0x2940: 0x3000, 0x2941: 0x3000, 0x2942: 0x3000, 0x2943: 0x3000, 0x2944: 0x3000, 0x2945: 0x3000, + 0x2946: 0x3000, 0x2947: 0x3000, 0x2948: 0x3000, 0x2949: 0x3000, 0x294a: 0x3000, + 0x2950: 0x3000, 0x2951: 0x3000, + 0x2952: 0x3000, 0x2953: 0x3000, 0x2954: 0x3000, 0x2955: 0x3000, 0x2956: 0x3000, 0x2957: 0x3000, + 0x2958: 0x3000, 0x2959: 0x3000, 0x295a: 0x3000, 0x295b: 0x3000, 0x295c: 0x3000, 0x295d: 0x3000, + 0x295e: 0x3000, 0x295f: 0x3000, 0x2960: 0x3000, 0x2961: 0x3000, 0x2962: 0x3000, 0x2963: 0x3000, + 0x2964: 0x3000, 0x2965: 0x3000, 0x2966: 0x3000, 0x2967: 0x3000, 0x2968: 0x3000, 0x2969: 0x3000, + 0x296a: 0x3000, 0x296b: 0x3000, 0x296c: 0x3000, 0x296d: 0x3000, 0x296e: 0x3000, + 0x2970: 0x3000, 0x2971: 0x3000, 0x2972: 0x3000, 0x2973: 0x3000, 0x2974: 0x3000, 0x2975: 0x3000, + 0x2976: 0x3000, 0x2977: 0x3000, 0x2978: 0x3000, 0x2979: 0x3000, 0x297a: 0x3000, 0x297b: 0x3000, + 0x297c: 0x3000, 0x297d: 0x3000, 0x297e: 0x3000, 0x297f: 0x3000, + // Block 0xa6, offset 0x2980 + 0x2980: 0x3000, 0x2981: 0x3000, 0x2982: 0x3000, 0x2983: 0x3000, 0x2984: 0x3000, 0x2985: 0x3000, + 0x2986: 0x3000, 0x2987: 0x3000, 0x2988: 0x3000, 0x2989: 0x3000, 0x298a: 0x3000, 0x298b: 0x3000, + 0x298c: 0x3000, 0x298d: 0x3000, 0x298e: 0x3000, 0x298f: 0x3000, + // Block 0xa7, offset 0x29c0 + 0x29d0: 0x3000, + // Block 0xa8, offset 0x2a00 + 0x2a00: 0x3000, 0x2a01: 0x3000, 0x2a02: 0x3000, + 0x2a10: 0x3000, 0x2a11: 0x3000, + 0x2a12: 0x3000, 0x2a13: 0x3000, 0x2a14: 0x3000, 0x2a15: 0x3000, 0x2a16: 0x3000, 0x2a17: 0x3000, + 0x2a18: 0x3000, 0x2a19: 0x3000, 0x2a1a: 0x3000, 0x2a1b: 0x3000, 0x2a1c: 0x3000, 0x2a1d: 0x3000, + 0x2a1e: 0x3000, 0x2a1f: 0x3000, 0x2a20: 0x3000, 0x2a21: 0x3000, 0x2a22: 0x3000, 0x2a23: 0x3000, + 0x2a24: 0x3000, 0x2a25: 0x3000, 0x2a26: 0x3000, 0x2a27: 0x3000, 0x2a28: 0x3000, 0x2a29: 0x3000, + 0x2a2a: 0x3000, 0x2a2b: 0x3000, 0x2a2c: 0x3000, 0x2a2d: 0x3000, 0x2a2e: 0x3000, 0x2a2f: 0x3000, + 0x2a30: 0x3000, 0x2a31: 0x3000, 0x2a32: 0x3000, 0x2a33: 0x3000, 0x2a34: 0x3000, 0x2a35: 0x3000, + 0x2a36: 0x3000, 0x2a37: 0x3000, 0x2a38: 0x3000, 0x2a39: 0x3000, 0x2a3a: 0x3000, + // Block 0xa9, offset 0x2a40 + 0x2a40: 0x3000, 0x2a41: 0x3000, 0x2a42: 0x3000, 0x2a43: 0x3000, 0x2a44: 0x3000, 0x2a45: 0x3000, + 0x2a46: 0x3000, 0x2a47: 0x3000, 0x2a48: 0x3000, + 0x2a50: 0x3000, 0x2a51: 0x3000, + // Block 0xaa, offset 0x2a80 + 0x2a80: 0x3300, 0x2a81: 0x3300, 0x2a82: 0x3300, 0x2a83: 0x3300, 0x2a84: 0x3300, 0x2a85: 0x3300, + 0x2a86: 0x3300, 0x2a87: 0x3300, 0x2a88: 0x3300, 0x2a89: 0x3300, 0x2a8a: 0x3300, 0x2a8b: 0x3300, + 0x2a8c: 0x3300, 0x2a8d: 0x3300, 0x2a8e: 0x3300, 0x2a8f: 0x3300, 0x2a90: 0x3300, 0x2a91: 0x3300, + 0x2a92: 0x3300, 0x2a93: 0x3300, 0x2a94: 0x3300, 0x2a95: 0x3300, 0x2a96: 0x3300, 0x2a97: 0x3300, + 0x2a98: 0x3300, 0x2a99: 0x3300, 0x2a9a: 0x3300, 0x2a9b: 0x3300, 0x2a9c: 0x3300, 0x2a9d: 0x3300, +} + +// charInfoLookup: 1152 bytes +// Block 0 is the null block. +var charInfoLookup = [1152]uint8{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0x0c2: 0x03, 0x0c3: 0x04, 0x0c4: 0x05, 0x0c5: 0x06, 0x0c6: 0x07, 0x0c7: 0x08, + 0x0c8: 0x09, 0x0ca: 0x0a, 0x0cb: 0x0b, 0x0cc: 0x0c, 0x0cd: 0x0d, 0x0ce: 0x0e, 0x0cf: 0x0f, + 0x0d0: 0x10, 0x0d1: 0x11, 0x0d2: 0x12, 0x0d3: 0x13, 0x0d6: 0x14, 0x0d7: 0x15, + 0x0d8: 0x16, 0x0d9: 0x17, 0x0db: 0x18, 0x0dc: 0x19, 0x0dd: 0x1a, 0x0df: 0x1b, + 0x0e0: 0x04, 0x0e1: 0x05, 0x0e2: 0x06, 0x0e3: 0x07, + 0x0ea: 0x08, 0x0eb: 0x09, 0x0ec: 0x09, 0x0ed: 0x0a, 0x0ef: 0x0b, + 0x0f0: 0x11, + // Block 0x4, offset 0x100 + 0x120: 0x1c, 0x121: 0x1d, 0x124: 0x1e, 0x125: 0x1f, 0x126: 0x20, 0x127: 0x21, + 0x128: 0x22, 0x129: 0x23, 0x12a: 0x24, 0x12b: 0x25, 0x12c: 0x20, 0x12d: 0x26, 0x12e: 0x27, 0x12f: 0x28, + 0x131: 0x29, 0x132: 0x2a, 0x133: 0x2b, 0x134: 0x2c, 0x135: 0x28, 0x137: 0x2d, + 0x138: 0x2e, 0x139: 0x2f, 0x13a: 0x30, 0x13b: 0x31, 0x13c: 0x32, 0x13d: 0x33, 0x13e: 0x34, 0x13f: 0x35, + // Block 0x5, offset 0x140 + 0x140: 0x36, 0x142: 0x37, 0x143: 0x38, 0x145: 0x39, 0x146: 0x3a, 0x147: 0x3b, + 0x14d: 0x3c, + 0x15c: 0x3d, 0x15f: 0x3e, + 0x162: 0x3f, 0x164: 0x40, + 0x168: 0x41, 0x169: 0x42, 0x16c: 0x43, 0x16d: 0x44, 0x16e: 0x45, 0x16f: 0x46, + 0x170: 0x47, 0x173: 0x48, 0x174: 0x49, 0x175: 0x4a, 0x176: 0x4b, 0x177: 0x4c, + 0x178: 0x4d, 0x179: 0x4e, 0x17a: 0x4f, 0x17b: 0x50, 0x17c: 0x51, 0x17d: 0x52, 0x17e: 0x53, 0x17f: 0x54, + // Block 0x6, offset 0x180 + 0x180: 0x55, 0x181: 0x56, 0x182: 0x57, 0x183: 0x58, 0x184: 0x59, 0x185: 0x5a, 0x186: 0x5b, 0x187: 0x5c, + 0x188: 0x5d, 0x189: 0x5e, 0x18a: 0x5f, 0x18b: 0x60, 0x18c: 0x61, + 0x191: 0x62, 0x192: 0x63, 0x193: 0x64, + 0x1a8: 0x65, 0x1a9: 0x66, 0x1ab: 0x67, + 0x1b1: 0x68, 0x1b3: 0x69, 0x1b5: 0x6a, 0x1b7: 0x6b, + 0x1ba: 0x6c, 0x1bb: 0x6d, 0x1bc: 0x63, 0x1bd: 0x63, 0x1be: 0x63, 0x1bf: 0x6e, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x6f, 0x1c1: 0x70, 0x1c2: 0x71, 0x1c3: 0x72, 0x1c4: 0x73, 0x1c5: 0x63, 0x1c6: 0x74, + 0x1c8: 0x75, 0x1c9: 0x76, 0x1ca: 0x63, 0x1cb: 0x77, 0x1cc: 0x63, 0x1cd: 0x63, 0x1ce: 0x63, 0x1cf: 0x63, + // Block 0x8, offset 0x200 + 0x219: 0x78, 0x21b: 0x79, 0x21d: 0x7a, + 0x220: 0x7b, 0x223: 0x7c, 0x224: 0x7d, 0x225: 0x7e, 0x226: 0x7f, 0x227: 0x80, + 0x22a: 0x81, 0x22b: 0x82, 0x22f: 0x83, + 0x230: 0x84, 0x231: 0x84, 0x232: 0x84, 0x233: 0x84, 0x234: 0x84, 0x235: 0x84, 0x236: 0x84, 0x237: 0x84, + 0x238: 0x84, 0x239: 0x84, 0x23a: 0x84, 0x23b: 0x84, 0x23c: 0x84, 0x23d: 0x84, 0x23e: 0x84, 0x23f: 0x84, + // Block 0x9, offset 0x240 + 0x240: 0x84, 0x241: 0x84, 0x242: 0x84, 0x243: 0x84, 0x244: 0x84, 0x245: 0x84, 0x246: 0x84, 0x247: 0x84, + 0x248: 0x84, 0x249: 0x84, 0x24a: 0x84, 0x24b: 0x84, 0x24c: 0x84, 0x24d: 0x84, 0x24e: 0x84, 0x24f: 0x84, + 0x250: 0x84, 0x251: 0x84, 0x252: 0x84, 0x253: 0x84, 0x254: 0x84, 0x255: 0x84, 0x256: 0x84, 0x257: 0x84, + 0x258: 0x84, 0x259: 0x84, 0x25a: 0x84, 0x25b: 0x84, 0x25c: 0x84, 0x25d: 0x84, 0x25e: 0x84, 0x25f: 0x84, + 0x260: 0x84, 0x261: 0x84, 0x262: 0x84, 0x263: 0x84, 0x264: 0x84, 0x265: 0x84, 0x266: 0x84, 0x267: 0x84, + 0x268: 0x84, 0x269: 0x84, 0x26a: 0x84, 0x26b: 0x84, 0x26c: 0x84, 0x26d: 0x84, 0x26e: 0x84, 0x26f: 0x84, + 0x270: 0x84, 0x271: 0x84, 0x272: 0x84, 0x273: 0x84, 0x274: 0x84, 0x275: 0x84, 0x276: 0x84, 0x277: 0x84, + 0x278: 0x84, 0x279: 0x84, 0x27a: 0x84, 0x27b: 0x84, 0x27c: 0x84, 0x27d: 0x84, 0x27e: 0x84, 0x27f: 0x84, + // Block 0xa, offset 0x280 + 0x280: 0x84, 0x281: 0x84, 0x282: 0x84, 0x283: 0x84, 0x284: 0x84, 0x285: 0x84, 0x286: 0x84, 0x287: 0x84, + 0x288: 0x84, 0x289: 0x84, 0x28a: 0x84, 0x28b: 0x84, 0x28c: 0x84, 0x28d: 0x84, 0x28e: 0x84, 0x28f: 0x84, + 0x290: 0x84, 0x291: 0x84, 0x292: 0x84, 0x293: 0x84, 0x294: 0x84, 0x295: 0x84, 0x296: 0x84, 0x297: 0x84, + 0x298: 0x84, 0x299: 0x84, 0x29a: 0x84, 0x29b: 0x84, 0x29c: 0x84, 0x29d: 0x84, 0x29e: 0x85, + // Block 0xb, offset 0x2c0 + 0x2e4: 0x86, 0x2e5: 0x86, 0x2e6: 0x86, 0x2e7: 0x86, + 0x2e8: 0x87, 0x2e9: 0x88, 0x2ea: 0x86, 0x2eb: 0x89, 0x2ec: 0x8a, 0x2ed: 0x8b, 0x2ee: 0x8c, 0x2ef: 0x8d, + 0x2f0: 0x63, 0x2f1: 0x63, 0x2f2: 0x63, 0x2f3: 0x63, 0x2f4: 0x8e, 0x2f5: 0x8f, 0x2f6: 0x90, 0x2f7: 0x91, + 0x2f8: 0x92, 0x2f9: 0x93, 0x2fa: 0x63, 0x2fb: 0x94, 0x2fc: 0x95, 0x2fd: 0x63, 0x2fe: 0x77, 0x2ff: 0x96, + // Block 0xc, offset 0x300 + 0x307: 0x97, + 0x328: 0x98, + // Block 0xd, offset 0x340 + 0x341: 0x7b, 0x342: 0x99, + // Block 0xe, offset 0x380 + 0x385: 0x9a, 0x386: 0x9b, 0x387: 0x9c, + 0x389: 0x9d, + 0x390: 0x63, 0x391: 0x9e, 0x392: 0x9f, 0x393: 0xa0, 0x394: 0xa1, 0x395: 0xa2, 0x396: 0x63, 0x397: 0x63, + 0x398: 0x63, 0x399: 0x63, 0x39a: 0xa3, 0x39b: 0x63, 0x39c: 0x63, 0x39d: 0x63, 0x39e: 0x63, 0x39f: 0xa4, + // Block 0xf, offset 0x3c0 + 0x3c4: 0xa5, 0x3c5: 0xa6, 0x3c6: 0xa7, + 0x3c8: 0xa8, 0x3c9: 0xa9, + // Block 0x10, offset 0x400 + 0x420: 0x86, 0x421: 0x86, 0x422: 0x86, 0x423: 0x86, 0x424: 0x86, 0x425: 0x86, 0x426: 0x86, 0x427: 0x86, + 0x428: 0xaa, + // Block 0x11, offset 0x440 + 0x450: 0x0c, 0x451: 0x0d, + 0x45d: 0x0e, 0x45f: 0x0f, + 0x46f: 0x10, +} + +var charInfoTrie = trie{charInfoLookup[:], charInfoValues[:]} + +// Total size of tables: 78KB (80234 bytes) diff --git a/libgo/go/exp/norm/trie.go b/libgo/go/exp/norm/trie.go new file mode 100644 index 00000000000..6b654018757 --- /dev/null +++ b/libgo/go/exp/norm/trie.go @@ -0,0 +1,234 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package norm + +type trie struct { + index []uint8 + values []uint16 +} + +const ( + t1 = 0x00 // 0000 0000 + tx = 0x80 // 1000 0000 + t2 = 0xC0 // 1100 0000 + t3 = 0xE0 // 1110 0000 + t4 = 0xF0 // 1111 0000 + t5 = 0xF8 // 1111 1000 + t6 = 0xFC // 1111 1100 + te = 0xFE // 1111 1110 + + maskx = 0x3F // 0011 1111 + mask2 = 0x1F // 0001 1111 + mask3 = 0x0F // 0000 1111 + mask4 = 0x07 // 0000 0111 +) + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *trie) lookup(s []byte) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < tx: + return t.values[c0], 1 + case c0 < t2: + return 0, 1 + case c0 < t3: + if len(s) < 2 { + return 0, 0 + } + i := t.index[c0] + c1 := s[1] + if c1 < tx || t2 <= c1 { + return 0, 1 + } + o := uint16(i)<<6 + uint16(c1)&maskx + return t.values[o], 2 + case c0 < t4: + if len(s) < 3 { + return 0, 0 + } + i := t.index[c0] + c1 := s[1] + if c1 < tx || t2 <= c1 { + return 0, 1 + } + o := uint16(i)<<6 + uint16(c1)&maskx + i = t.index[o] + c2 := s[2] + if c2 < tx || t2 <= c2 { + return 0, 2 + } + o = uint16(i)<<6 + uint16(c2)&maskx + return t.values[o], 3 + case c0 < t5: + if len(s) < 4 { + return 0, 0 + } + i := t.index[c0] + c1 := s[1] + if c1 < tx || t2 <= c1 { + return 0, 1 + } + o := uint16(i)<<6 + uint16(c1)&maskx + i = t.index[o] + c2 := s[2] + if c2 < tx || t2 <= c2 { + return 0, 2 + } + o = uint16(i)<<6 + uint16(c2)&maskx + i = t.index[o] + c3 := s[3] + if c3 < tx || t2 <= c3 { + return 0, 3 + } + o = uint16(i)<<6 + uint16(c3)&maskx + return t.values[o], 4 + case c0 < t6: + if len(s) < 5 { + return 0, 0 + } + return 0, 5 + case c0 < te: + if len(s) < 6 { + return 0, 0 + } + return 0, 6 + } + // Illegal rune + return 0, 1 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *trie) lookupString(s string) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < tx: + return t.values[c0], 1 + case c0 < t2: + return 0, 1 + case c0 < t3: + if len(s) < 2 { + return 0, 0 + } + i := t.index[c0] + c1 := s[1] + if c1 < tx || t2 <= c1 { + return 0, 1 + } + o := uint16(i)<<6 + uint16(c1)&maskx + return t.values[o], 2 + case c0 < t4: + if len(s) < 3 { + return 0, 0 + } + i := t.index[c0] + c1 := s[1] + if c1 < tx || t2 <= c1 { + return 0, 1 + } + o := uint16(i)<<6 + uint16(c1)&maskx + i = t.index[o] + c2 := s[2] + if c2 < tx || t2 <= c2 { + return 0, 2 + } + o = uint16(i)<<6 + uint16(c2)&maskx + return t.values[o], 3 + case c0 < t5: + if len(s) < 4 { + return 0, 0 + } + i := t.index[c0] + c1 := s[1] + if c1 < tx || t2 <= c1 { + return 0, 1 + } + o := uint16(i)<<6 + uint16(c1)&maskx + i = t.index[o] + c2 := s[2] + if c2 < tx || t2 <= c2 { + return 0, 2 + } + o = uint16(i)<<6 + uint16(c2)&maskx + i = t.index[o] + c3 := s[3] + if c3 < tx || t2 <= c3 { + return 0, 3 + } + o = uint16(i)<<6 + uint16(c3)&maskx + return t.values[o], 4 + case c0 < t6: + if len(s) < 5 { + return 0, 0 + } + return 0, 5 + case c0 < te: + if len(s) < 6 { + return 0, 0 + } + return 0, 6 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must hold a full encoding. +func (t *trie) lookupUnsafe(s []byte) uint16 { + c0 := s[0] + if c0 < tx { + return t.values[c0] + } + if c0 < t2 { + return 0 + } + i := t.index[c0] + o := uint16(i)<<6 + uint16(s[1])&maskx + if c0 < t3 { + return t.values[o] + } + i = t.index[o] + o = uint16(i)<<6 + uint16(s[2])&maskx + if c0 < t4 { + return t.values[o] + } + i = t.index[o] + o = uint16(i)<<6 + uint16(s[3])&maskx + if c0 < t5 { + return t.values[o] + } + return 0 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must hold a full encoding. +func (t *trie) lookupStringUnsafe(s string) uint16 { + c0 := s[0] + if c0 < tx { + return t.values[c0] + } + if c0 < t2 { + return 0 + } + i := t.index[c0] + o := uint16(i)<<6 + uint16(s[1])&maskx + if c0 < t3 { + return t.values[o] + } + i = t.index[o] + o = uint16(i)<<6 + uint16(s[2])&maskx + if c0 < t4 { + return t.values[o] + } + i = t.index[o] + o = uint16(i)<<6 + uint16(s[3])&maskx + if c0 < t5 { + return t.values[o] + } + return 0 +} diff --git a/libgo/go/exp/norm/trie_test.go b/libgo/go/exp/norm/trie_test.go new file mode 100644 index 00000000000..ad87d972b02 --- /dev/null +++ b/libgo/go/exp/norm/trie_test.go @@ -0,0 +1,107 @@ +package norm + +import ( + "testing" + "utf8" +) + +// Test data is located in triedata_test.go; generated by maketesttables. +var testdata = testdataTrie + +// Test cases for illegal runes. +type trietest struct { + size int + bytes []byte +} + +var tests = []trietest{ + // illegal runes + {1, []byte{0x80}}, + {1, []byte{0xFF}}, + {1, []byte{t2, tx - 1}}, + {1, []byte{t2, t2}}, + {2, []byte{t3, tx, tx - 1}}, + {2, []byte{t3, tx, t2}}, + {1, []byte{t3, tx - 1, tx}}, + {3, []byte{t4, tx, tx, tx - 1}}, + {3, []byte{t4, tx, tx, t2}}, + {1, []byte{t4, t2, tx, tx - 1}}, + {2, []byte{t4, tx, t2, tx - 1}}, + + // short runes + {0, []byte{t2}}, + {0, []byte{t3, tx}}, + {0, []byte{t4, tx, tx}}, + {0, []byte{t5, tx, tx, tx}}, + {0, []byte{t6, tx, tx, tx, tx}}, +} + +func mkUtf8(rune int) ([]byte, int) { + var b [utf8.UTFMax]byte + sz := utf8.EncodeRune(b[:], rune) + return b[:sz], sz +} + +func TestLookup(t *testing.T) { + for i, tt := range testRunes { + b, szg := mkUtf8(tt) + v, szt := testdata.lookup(b) + if int(v) != i { + t.Errorf("lookup(%U): found value %#x, expected %#x", i, v, i) + } + if szt != szg { + t.Errorf("lookup(%U): found size %d, expected %d", i, szt, szg) + } + } + for i, tt := range tests { + v, sz := testdata.lookup(tt.bytes) + if int(v) != 0 { + t.Errorf("lookup of illegal rune, case %d: found value %#x, expected 0", i, v) + } + if sz != tt.size { + t.Errorf("lookup of illegal rune, case %d: found size %d, expected %d", i, sz, tt.size) + } + } +} + +func TestLookupUnsafe(t *testing.T) { + for i, tt := range testRunes { + b, _ := mkUtf8(tt) + v := testdata.lookupUnsafe(b) + if int(v) != i { + t.Errorf("lookupUnsafe(%U): found value %#x, expected %#x", i, v, i) + } + } +} + +func TestLookupString(t *testing.T) { + for i, tt := range testRunes { + b, szg := mkUtf8(tt) + v, szt := testdata.lookupString(string(b)) + if int(v) != i { + t.Errorf("lookup(%U): found value %#x, expected %#x", i, v, i) + } + if szt != szg { + t.Errorf("lookup(%U): found size %d, expected %d", i, szt, szg) + } + } + for i, tt := range tests { + v, sz := testdata.lookupString(string(tt.bytes)) + if int(v) != 0 { + t.Errorf("lookup of illegal rune, case %d: found value %#x, expected 0", i, v) + } + if sz != tt.size { + t.Errorf("lookup of illegal rune, case %d: found size %d, expected %d", i, sz, tt.size) + } + } +} + +func TestLookupStringUnsafe(t *testing.T) { + for i, tt := range testRunes { + b, _ := mkUtf8(tt) + v := testdata.lookupStringUnsafe(string(b)) + if int(v) != i { + t.Errorf("lookupUnsafe(%U): found value %#x, expected %#x", i, v, i) + } + } +} diff --git a/libgo/go/exp/norm/triedata_test.go b/libgo/go/exp/norm/triedata_test.go new file mode 100644 index 00000000000..f886e6004a4 --- /dev/null +++ b/libgo/go/exp/norm/triedata_test.go @@ -0,0 +1,63 @@ +// Generated by running +// maketesttables +// DO NOT EDIT + +package norm + +var testRunes = []int{1, 12, 127, 128, 256, 2047, 2048, 2457, 65535, 65536, 65793, 1114111} + +// testdataValues: 768 entries, 1536 bytes +// Block 2 is the null block. +var testdataValues = [768]uint16{ + // Block 0x0, offset 0x0 + 0x000c: 0x0001, + // Block 0x1, offset 0x40 + 0x007f: 0x0002, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0x00c0: 0x0003, + // Block 0x4, offset 0x100 + 0x0100: 0x0004, + // Block 0x5, offset 0x140 + 0x017f: 0x0005, + // Block 0x6, offset 0x180 + 0x0180: 0x0006, + // Block 0x7, offset 0x1c0 + 0x01d9: 0x0007, + // Block 0x8, offset 0x200 + 0x023f: 0x0008, + // Block 0x9, offset 0x240 + 0x0240: 0x0009, + // Block 0xa, offset 0x280 + 0x0281: 0x000a, + // Block 0xb, offset 0x2c0 + 0x02ff: 0x000b, +} + +// testdataLookup: 640 bytes +// Block 0 is the null block. +var testdataLookup = [640]uint8{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0x0c2: 0x03, 0x0c4: 0x04, + 0x0df: 0x05, + 0x0e0: 0x04, + 0x0ef: 0x05, + 0x0f0: 0x07, 0x0f4: 0x09, + // Block 0x4, offset 0x100 + 0x120: 0x06, 0x126: 0x07, + // Block 0x5, offset 0x140 + 0x17f: 0x08, + // Block 0x6, offset 0x180 + 0x180: 0x09, 0x184: 0x0a, + // Block 0x7, offset 0x1c0 + 0x1d0: 0x06, + // Block 0x8, offset 0x200 + 0x23f: 0x0b, + // Block 0x9, offset 0x240 + 0x24f: 0x08, +} + +var testdataTrie = trie{testdataLookup[:], testdataValues[:]} diff --git a/libgo/go/exp/norm/triegen.go b/libgo/go/exp/norm/triegen.go new file mode 100644 index 00000000000..2b7eeee175b --- /dev/null +++ b/libgo/go/exp/norm/triegen.go @@ -0,0 +1,211 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Trie table generator. +// Used by make*tables tools to generate a go file with trie data structures +// for mapping UTF-8 to a 16-bit value. All but the last byte in a UTF-8 byte +// sequence are used to lookup offsets in the index table to be used for the +// next byte. The last byte is used to index into a table with 16-bit values. + +package main + +import ( + "fmt" + "hash/crc32" + "log" + "utf8" +) + +// Intermediate trie structure +type trieNode struct { + table [256]*trieNode + value uint16 + b byte + leaf bool +} + +func newNode() *trieNode { + return new(trieNode) +} + +func (n trieNode) String() string { + s := fmt.Sprint("trieNode{table: { non-nil at index: ") + for i, v := range n.table { + if v != nil { + s += fmt.Sprintf("%d, ", i) + } + } + s += fmt.Sprintf("}, value:%#x, b:%#x leaf:%v}", n.value, n.b, n.leaf) + return s +} + +func (n trieNode) isInternal() bool { + internal := true + for i := 0; i < 256; i++ { + if nn := n.table[i]; nn != nil { + if !internal && !nn.leaf { + log.Fatalf("triegen: isInternal: node contains both leaf and non-leaf children (%v)", n) + } + internal = internal && !nn.leaf + } + } + return internal +} + +func (n *trieNode) insert(rune int, value uint16) { + var p [utf8.UTFMax]byte + sz := utf8.EncodeRune(p[:], rune) + + for i := 0; i < sz; i++ { + if n.leaf { + log.Fatalf("triegen: insert: node (%#v) should not be a leaf", n) + } + nn := n.table[p[i]] + if nn == nil { + nn = newNode() + nn.b = p[i] + n.table[p[i]] = nn + } + n = nn + } + n.value = value + n.leaf = true +} + +type nodeIndex struct { + lookupBlocks []*trieNode + valueBlocks []*trieNode + + lookupBlockIdx map[uint32]uint16 + valueBlockIdx map[uint32]uint16 +} + +func newIndex() *nodeIndex { + index := &nodeIndex{} + index.lookupBlocks = make([]*trieNode, 0) + index.valueBlocks = make([]*trieNode, 0) + index.lookupBlockIdx = make(map[uint32]uint16) + index.valueBlockIdx = make(map[uint32]uint16) + return index +} + +func computeOffsets(index *nodeIndex, n *trieNode) uint16 { + if n.leaf { + return n.value + } + hasher := crc32.New(crc32.MakeTable(crc32.IEEE)) + // We only index continuation bytes. + for i := 0; i < 64; i++ { + var v uint16 = 0 + if nn := n.table[0x80+i]; nn != nil { + v = computeOffsets(index, nn) + } + hasher.Write([]byte{uint8(v >> 8), uint8(v)}) + } + h := hasher.Sum32() + if n.isInternal() { + v, ok := index.lookupBlockIdx[h] + if !ok { + v = uint16(len(index.lookupBlocks)) + index.lookupBlocks = append(index.lookupBlocks, n) + index.lookupBlockIdx[h] = v + } + n.value = v + } else { + v, ok := index.valueBlockIdx[h] + if !ok { + v = uint16(len(index.valueBlocks)) + index.valueBlocks = append(index.valueBlocks, n) + index.valueBlockIdx[h] = v + } + n.value = v + } + return n.value +} + +func printValueBlock(nr int, n *trieNode, offset int) { + boff := nr * 64 + fmt.Printf("\n// Block %#x, offset %#x", nr, boff) + var printnewline bool + for i := 0; i < 64; i++ { + if i%6 == 0 { + printnewline = true + } + v := uint16(0) + if nn := n.table[i+offset]; nn != nil { + v = nn.value + } + if v != 0 { + if printnewline { + fmt.Printf("\n") + printnewline = false + } + fmt.Printf("%#04x:%#04x, ", nr*64+i, v) + } + } +} + +func printLookupBlock(nr int, n *trieNode, offset int) { + boff := nr * 64 + fmt.Printf("\n// Block %#x, offset %#x", nr, boff) + var printnewline bool + for i := 0; i < 64; i++ { + if i%8 == 0 { + printnewline = true + } + v := uint16(0) + if nn := n.table[i+offset]; nn != nil { + v = nn.value + } + if v != 0 { + if printnewline { + fmt.Printf("\n") + printnewline = false + } + fmt.Printf("%#03x:%#02x, ", boff+i, v) + } + } +} + +// printTables returns the size in bytes of the generated tables. +func (t *trieNode) printTables(name string) int { + index := newIndex() + // Values for 7-bit ASCII are stored in first two block, followed by nil block. + index.valueBlocks = append(index.valueBlocks, nil, nil, nil) + // First byte of multi-byte UTF-8 codepoints are indexed in 4th block. + index.lookupBlocks = append(index.lookupBlocks, nil, nil, nil, nil) + // Index starter bytes of multi-byte UTF-8. + for i := 0xC0; i < 0x100; i++ { + if t.table[i] != nil { + computeOffsets(index, t.table[i]) + } + } + + nv := len(index.valueBlocks) * 64 + fmt.Printf("// %sValues: %d entries, %d bytes\n", name, nv, nv*2) + fmt.Printf("// Block 2 is the null block.\n") + fmt.Printf("var %sValues = [%d]uint16 {", name, nv) + printValueBlock(0, t, 0) + printValueBlock(1, t, 64) + printValueBlock(2, newNode(), 0) + for i := 3; i < len(index.valueBlocks); i++ { + printValueBlock(i, index.valueBlocks[i], 0x80) + } + fmt.Print("\n}\n\n") + + ni := len(index.lookupBlocks) * 64 + fmt.Printf("// %sLookup: %d bytes\n", name, ni) + fmt.Printf("// Block 0 is the null block.\n") + fmt.Printf("var %sLookup = [%d]uint8 {", name, ni) + printLookupBlock(0, newNode(), 0) + printLookupBlock(1, newNode(), 0) + printLookupBlock(2, newNode(), 0) + printLookupBlock(3, t, 0xC0) + for i := 4; i < len(index.lookupBlocks); i++ { + printLookupBlock(i, index.lookupBlocks[i], 0x80) + } + fmt.Print("\n}\n\n") + fmt.Printf("var %sTrie = trie{ %sLookup[:], %sValues[:] }\n\n", name, name, name) + return nv*2 + ni +} diff --git a/libgo/go/exp/ogle/abort.go b/libgo/go/exp/ogle/abort.go deleted file mode 100644 index 311a7b38e24..00000000000 --- a/libgo/go/exp/ogle/abort.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ogle - -import ( - "os" - "runtime" -) - -// An aborter aborts the thread's current computation, usually -// passing the error to a waiting thread. -type aborter interface { - Abort(err os.Error) -} - -type ogleAborter chan os.Error - -func (a ogleAborter) Abort(err os.Error) { - a <- err - runtime.Goexit() -} - -// try executes a computation; if the computation Aborts, try returns -// the error passed to abort. -func try(f func(a aborter)) os.Error { - a := make(ogleAborter) - go func() { - f(a) - a <- nil - }() - err := <-a - return err -} diff --git a/libgo/go/exp/ogle/arch.go b/libgo/go/exp/ogle/arch.go deleted file mode 100644 index 52b1c97572b..00000000000 --- a/libgo/go/exp/ogle/arch.go +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ogle - -import ( - "debug/proc" - "math" -) - -type Arch interface { - // ToWord converts an array of up to 8 bytes in memory order - // to a word. - ToWord(data []byte) proc.Word - // FromWord converts a word to an array of up to 8 bytes in - // memory order. - FromWord(v proc.Word, out []byte) - // ToFloat32 converts a word to a float. The order of this - // word will be the order returned by ToWord on the memory - // representation of a float, and thus may require reversing. - ToFloat32(bits uint32) float32 - // FromFloat32 converts a float to a word. This should return - // a word that can be passed to FromWord to get the memory - // representation of a float on this architecture. - FromFloat32(f float32) uint32 - // ToFloat64 is to float64 as ToFloat32 is to float32. - ToFloat64(bits uint64) float64 - // FromFloat64 is to float64 as FromFloat32 is to float32. - FromFloat64(f float64) uint64 - - // IntSize returns the number of bytes in an 'int'. - IntSize() int - // PtrSize returns the number of bytes in a 'uintptr'. - PtrSize() int - // FloatSize returns the number of bytes in a 'float'. - FloatSize() int - // Align rounds offset up to the appropriate offset for a - // basic type with the given width. - Align(offset, width int) int - - // G returns the current G pointer. - G(regs proc.Regs) proc.Word - - // ClosureSize returns the number of bytes expected by - // ParseClosure. - ClosureSize() int - // ParseClosure takes ClosureSize bytes read from a return PC - // in a remote process, determines if the code is a closure, - // and returns the frame size of the closure if it is. - ParseClosure(data []byte) (frame int, ok bool) -} - -type ArchLSB struct{} - -func (ArchLSB) ToWord(data []byte) proc.Word { - var v proc.Word - for i, b := range data { - v |= proc.Word(b) << (uint(i) * 8) - } - return v -} - -func (ArchLSB) FromWord(v proc.Word, out []byte) { - for i := range out { - out[i] = byte(v) - v >>= 8 - } -} - -func (ArchLSB) ToFloat32(bits uint32) float32 { - // TODO(austin) Do these definitions depend on my current - // architecture? - return math.Float32frombits(bits) -} - -func (ArchLSB) FromFloat32(f float32) uint32 { return math.Float32bits(f) } - -func (ArchLSB) ToFloat64(bits uint64) float64 { return math.Float64frombits(bits) } - -func (ArchLSB) FromFloat64(f float64) uint64 { return math.Float64bits(f) } - -type ArchAlignedMultiple struct{} - -func (ArchAlignedMultiple) Align(offset, width int) int { - return ((offset - 1) | (width - 1)) + 1 -} - -type amd64 struct { - ArchLSB - ArchAlignedMultiple - gReg int -} - -func (a *amd64) IntSize() int { return 4 } - -func (a *amd64) PtrSize() int { return 8 } - -func (a *amd64) FloatSize() int { return 4 } - -func (a *amd64) G(regs proc.Regs) proc.Word { - // See src/pkg/runtime/mkasmh - if a.gReg == -1 { - ns := regs.Names() - for i, n := range ns { - if n == "r15" { - a.gReg = i - break - } - } - } - - return regs.Get(a.gReg) -} - -func (a *amd64) ClosureSize() int { return 8 } - -func (a *amd64) ParseClosure(data []byte) (int, bool) { - if data[0] == 0x48 && data[1] == 0x81 && data[2] == 0xc4 && data[7] == 0xc3 { - return int(a.ToWord(data[3:7]) + 8), true - } - return 0, false -} - -var Amd64 = &amd64{gReg: -1} diff --git a/libgo/go/exp/ogle/cmd.go b/libgo/go/exp/ogle/cmd.go deleted file mode 100644 index a8db523ea18..00000000000 --- a/libgo/go/exp/ogle/cmd.go +++ /dev/null @@ -1,373 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package ogle is the beginning of a debugger for Go. -package ogle - -import ( - "bufio" - "debug/elf" - "debug/proc" - "exp/eval" - "fmt" - "go/scanner" - "go/token" - "os" - "strconv" - "strings" -) - -var fset = token.NewFileSet() -var world *eval.World -var curProc *Process - -func Main() { - world = eval.NewWorld() - defineFuncs() - r := bufio.NewReader(os.Stdin) - for { - print("; ") - line, err := r.ReadSlice('\n') - if err != nil { - break - } - - // Try line as a command - cmd, rest := getCmd(line) - if cmd != nil { - err := cmd.handler(rest) - if err != nil { - scanner.PrintError(os.Stderr, err) - } - continue - } - - // Try line as code - code, err := world.Compile(fset, string(line)) - if err != nil { - scanner.PrintError(os.Stderr, err) - continue - } - v, err := code.Run() - if err != nil { - fmt.Fprintf(os.Stderr, err.String()) - continue - } - if v != nil { - println(v.String()) - } - } -} - -// newScanner creates a new scanner that scans that given input bytes. -func newScanner(input []byte) (*scanner.Scanner, *scanner.ErrorVector) { - sc := new(scanner.Scanner) - ev := new(scanner.ErrorVector) - file := fset.AddFile("input", fset.Base(), len(input)) - sc.Init(file, input, ev, 0) - return sc, ev -} - -/* - * Commands - */ - -// A UsageError occurs when a command is called with illegal arguments. -type UsageError string - -func (e UsageError) String() string { return string(e) } - -// A cmd represents a single command with a handler. -type cmd struct { - cmd string - handler func([]byte) os.Error -} - -var cmds = []cmd{ - {"load", cmdLoad}, - {"bt", cmdBt}, -} - -// getCmd attempts to parse an input line as a registered command. If -// successful, it returns the command and the bytes remaining after -// the command, which should be passed to the command. -func getCmd(line []byte) (*cmd, []byte) { - sc, _ := newScanner(line) - pos, tok, lit := sc.Scan() - if sc.ErrorCount != 0 || tok != token.IDENT { - return nil, nil - } - - slit := string(lit) - for i := range cmds { - if cmds[i].cmd == slit { - return &cmds[i], line[fset.Position(pos).Offset+len(lit):] - } - } - return nil, nil -} - -// cmdLoad starts or attaches to a process. Its form is similar to -// import: -// -// load [sym] "path" [;] -// -// sym specifies the name to give to the process. If not given, the -// name is derived from the path of the process. If ".", then the -// packages from the remote process are defined into the current -// namespace. If given, this symbol is defined as a package -// containing the process' packages. -// -// path gives the path of the process to start or attach to. If it is -// "pid:<num>", then attach to the given PID. Otherwise, treat it as -// a file path and space-separated arguments and start a new process. -// -// load always sets the current process to the loaded process. -func cmdLoad(args []byte) os.Error { - ident, path, err := parseLoad(args) - if err != nil { - return err - } - if curProc != nil { - return UsageError("multiple processes not implemented") - } - if ident != "." { - return UsageError("process identifiers not implemented") - } - - // Parse argument and start or attach to process - var fname string - var tproc proc.Process - if len(path) >= 4 && path[0:4] == "pid:" { - pid, err := strconv.Atoi(path[4:]) - if err != nil { - return err - } - fname, err = os.Readlink(fmt.Sprintf("/proc/%d/exe", pid)) - if err != nil { - return err - } - tproc, err = proc.Attach(pid) - if err != nil { - return err - } - println("Attached to", pid) - } else { - parts := strings.Split(path, " ", -1) - if len(parts) == 0 { - fname = "" - } else { - fname = parts[0] - } - tproc, err = proc.StartProcess(fname, parts, &os.ProcAttr{Files: []*os.File{os.Stdin, os.Stdout, os.Stderr}}) - if err != nil { - return err - } - println("Started", path) - // TODO(austin) If we fail after this point, kill tproc - // before detaching. - } - - // Get symbols - f, err := os.Open(fname) - if err != nil { - tproc.Detach() - return err - } - defer f.Close() - elf, err := elf.NewFile(f) - if err != nil { - tproc.Detach() - return err - } - curProc, err = NewProcessElf(tproc, elf) - if err != nil { - tproc.Detach() - return err - } - - // Prepare new process - curProc.OnGoroutineCreate().AddHandler(EventPrint) - curProc.OnGoroutineExit().AddHandler(EventPrint) - - err = curProc.populateWorld(world) - if err != nil { - tproc.Detach() - return err - } - - return nil -} - -func parseLoad(args []byte) (ident string, path string, err os.Error) { - err = UsageError("Usage: load [sym] \"path\"") - sc, ev := newScanner(args) - - var toks [4]token.Token - var lits [4]string - for i := range toks { - _, toks[i], lits[i] = sc.Scan() - } - if sc.ErrorCount != 0 { - err = ev.GetError(scanner.NoMultiples) - return - } - - i := 0 - switch toks[i] { - case token.PERIOD, token.IDENT: - ident = string(lits[i]) - i++ - } - - if toks[i] != token.STRING { - return - } - path, uerr := strconv.Unquote(string(lits[i])) - if uerr != nil { - err = uerr - return - } - i++ - - if toks[i] == token.SEMICOLON { - i++ - } - if toks[i] != token.EOF { - return - } - - return ident, path, nil -} - -// cmdBt prints a backtrace for the current goroutine. It takes no -// arguments. -func cmdBt(args []byte) os.Error { - err := parseNoArgs(args, "Usage: bt") - if err != nil { - return err - } - - if curProc == nil || curProc.curGoroutine == nil { - return NoCurrentGoroutine{} - } - - f := curProc.curGoroutine.frame - if f == nil { - fmt.Println("No frames on stack") - return nil - } - - for f.Inner() != nil { - f = f.Inner() - } - - for i := 0; i < 100; i++ { - if f == curProc.curGoroutine.frame { - fmt.Printf("=> ") - } else { - fmt.Printf(" ") - } - fmt.Printf("%8x %v\n", f.pc, f) - f, err = f.Outer() - if err != nil { - return err - } - if f == nil { - return nil - } - } - - fmt.Println("...") - return nil -} - -func parseNoArgs(args []byte, usage string) os.Error { - sc, ev := newScanner(args) - _, tok, _ := sc.Scan() - if sc.ErrorCount != 0 { - return ev.GetError(scanner.NoMultiples) - } - if tok != token.EOF { - return UsageError(usage) - } - return nil -} - -/* - * Functions - */ - -// defineFuncs populates world with the built-in functions. -func defineFuncs() { - t, v := eval.FuncFromNativeTyped(fnOut, fnOutSig) - world.DefineConst("Out", t, v) - t, v = eval.FuncFromNativeTyped(fnContWait, fnContWaitSig) - world.DefineConst("ContWait", t, v) - t, v = eval.FuncFromNativeTyped(fnBpSet, fnBpSetSig) - world.DefineConst("BpSet", t, v) -} - -// printCurFrame prints the current stack frame, as it would appear in -// a backtrace. -func printCurFrame() { - if curProc == nil || curProc.curGoroutine == nil { - return - } - f := curProc.curGoroutine.frame - if f == nil { - return - } - fmt.Printf("=> %8x %v\n", f.pc, f) -} - -// fnOut moves the current frame to the caller of the current frame. -func fnOutSig() {} -func fnOut(t *eval.Thread, args []eval.Value, res []eval.Value) { - if curProc == nil { - t.Abort(NoCurrentGoroutine{}) - } - err := curProc.Out() - if err != nil { - t.Abort(err) - } - // TODO(austin) Only in the command form - printCurFrame() -} - -// fnContWait continues the current process and waits for a stopping event. -func fnContWaitSig() {} -func fnContWait(t *eval.Thread, args []eval.Value, res []eval.Value) { - if curProc == nil { - t.Abort(NoCurrentGoroutine{}) - } - err := curProc.ContWait() - if err != nil { - t.Abort(err) - } - // TODO(austin) Only in the command form - ev := curProc.Event() - if ev != nil { - fmt.Printf("%v\n", ev) - } - printCurFrame() -} - -// fnBpSet sets a breakpoint at the entry to the named function. -func fnBpSetSig(string) {} -func fnBpSet(t *eval.Thread, args []eval.Value, res []eval.Value) { - // TODO(austin) This probably shouldn't take a symbol name. - // Perhaps it should take an interface that provides PC's. - // Functions and instructions can implement that interface and - // we can have something to translate file:line pairs. - if curProc == nil { - t.Abort(NoCurrentGoroutine{}) - } - name := args[0].(eval.StringValue).Get(t) - fn := curProc.syms.LookupFunc(name) - if fn == nil { - t.Abort(UsageError("no such function " + name)) - } - curProc.OnBreakpoint(proc.Word(fn.Entry)).AddHandler(EventStop) -} diff --git a/libgo/go/exp/ogle/event.go b/libgo/go/exp/ogle/event.go deleted file mode 100644 index d7092ded336..00000000000 --- a/libgo/go/exp/ogle/event.go +++ /dev/null @@ -1,280 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ogle - -import ( - "debug/proc" - "fmt" - "os" -) - -/* - * Hooks and events - */ - -// An EventHandler is a function that takes an event and returns a -// response to that event and possibly an error. If an event handler -// returns an error, the process stops and no other handlers for that -// event are executed. -type EventHandler func(e Event) (EventAction, os.Error) - -// An EventAction is an event handler's response to an event. If all -// of an event's handlers execute without returning errors, their -// results are combined as follows: If any handler returned -// EAContinue, then the process resumes (without returning from -// WaitStop); otherwise, if any handler returned EAStop, the process -// remains stopped; otherwise, if all handlers returned EADefault, the -// process resumes. A handler may return EARemoveSelf bit-wise or'd -// with any other action to indicate that the handler should be -// removed from the hook. -type EventAction int - -const ( - EARemoveSelf EventAction = 0x100 - EADefault EventAction = iota - EAStop - EAContinue -) - -// A EventHook allows event handlers to be added and removed. -type EventHook interface { - AddHandler(EventHandler) - RemoveHandler(EventHandler) - NumHandler() int - handle(e Event) (EventAction, os.Error) - String() string -} - -// EventHook is almost, but not quite, suitable for user-defined -// events. If we want user-defined events, make EventHook a struct, -// special-case adding and removing handlers in breakpoint hooks, and -// provide a public interface for posting events to hooks. - -type Event interface { - Process() *Process - Goroutine() *Goroutine - String() string -} - -type commonHook struct { - // Head of handler chain - head *handler - // Number of non-internal handlers - len int -} - -type handler struct { - eh EventHandler - // True if this handler must be run before user-defined - // handlers in order to ensure correctness. - internal bool - // True if this handler has been removed from the chain. - removed bool - next *handler -} - -func (h *commonHook) AddHandler(eh EventHandler) { - h.addHandler(eh, false) -} - -func (h *commonHook) addHandler(eh EventHandler, internal bool) { - // Ensure uniqueness of handlers - h.RemoveHandler(eh) - - if !internal { - h.len++ - } - // Add internal handlers to the beginning - if internal || h.head == nil { - h.head = &handler{eh, internal, false, h.head} - return - } - // Add handler after internal handlers - // TODO(austin) This should probably go on the end instead - prev := h.head - for prev.next != nil && prev.internal { - prev = prev.next - } - prev.next = &handler{eh, internal, false, prev.next} -} - -func (h *commonHook) RemoveHandler(eh EventHandler) { - plink := &h.head - for l := *plink; l != nil; plink, l = &l.next, l.next { - if l.eh == eh { - if !l.internal { - h.len-- - } - l.removed = true - *plink = l.next - break - } - } -} - -func (h *commonHook) NumHandler() int { return h.len } - -func (h *commonHook) handle(e Event) (EventAction, os.Error) { - action := EADefault - plink := &h.head - for l := *plink; l != nil; plink, l = &l.next, l.next { - if l.removed { - continue - } - a, err := l.eh(e) - if a&EARemoveSelf == EARemoveSelf { - if !l.internal { - h.len-- - } - l.removed = true - *plink = l.next - a &^= EARemoveSelf - } - if err != nil { - return EAStop, err - } - if a > action { - action = a - } - } - return action, nil -} - -type commonEvent struct { - // The process of this event - p *Process - // The goroutine of this event. - t *Goroutine -} - -func (e *commonEvent) Process() *Process { return e.p } - -func (e *commonEvent) Goroutine() *Goroutine { return e.t } - -/* - * Standard event handlers - */ - -// EventPrint is a standard event handler that prints events as they -// occur. It will not cause the process to stop. -func EventPrint(ev Event) (EventAction, os.Error) { - // TODO(austin) Include process name here? - fmt.Fprintf(os.Stderr, "*** %v\n", ev.String()) - return EADefault, nil -} - -// EventStop is a standard event handler that causes the process to stop. -func EventStop(ev Event) (EventAction, os.Error) { - return EAStop, nil -} - -/* - * Breakpoints - */ - -type breakpointHook struct { - commonHook - p *Process - pc proc.Word -} - -// A Breakpoint event occurs when a process reaches a particular -// program counter. When this event is handled, the current goroutine -// will be the goroutine that reached the program counter. -type Breakpoint struct { - commonEvent - osThread proc.Thread - pc proc.Word -} - -func (h *breakpointHook) AddHandler(eh EventHandler) { - h.addHandler(eh, false) -} - -func (h *breakpointHook) addHandler(eh EventHandler, internal bool) { - // We register breakpoint events lazily to avoid holding - // references to breakpoints without handlers. Be sure to use - // the "canonical" breakpoint if there is one. - if cur, ok := h.p.breakpointHooks[h.pc]; ok { - h = cur - } - oldhead := h.head - h.commonHook.addHandler(eh, internal) - if oldhead == nil && h.head != nil { - h.p.proc.AddBreakpoint(h.pc) - h.p.breakpointHooks[h.pc] = h - } -} - -func (h *breakpointHook) RemoveHandler(eh EventHandler) { - oldhead := h.head - h.commonHook.RemoveHandler(eh) - if oldhead != nil && h.head == nil { - h.p.proc.RemoveBreakpoint(h.pc) - h.p.breakpointHooks[h.pc] = nil, false - } -} - -func (h *breakpointHook) String() string { - // TODO(austin) Include process name? - // TODO(austin) Use line:pc or at least sym+%#x - return fmt.Sprintf("breakpoint at %#x", h.pc) -} - -func (b *Breakpoint) PC() proc.Word { return b.pc } - -func (b *Breakpoint) String() string { - // TODO(austin) Include process name and goroutine - // TODO(austin) Use line:pc or at least sym+%#x - return fmt.Sprintf("breakpoint at %#x", b.pc) -} - -/* - * Goroutine create/exit - */ - -type goroutineCreateHook struct { - commonHook -} - -func (h *goroutineCreateHook) String() string { return "goroutine create" } - -// A GoroutineCreate event occurs when a process creates a new -// goroutine. When this event is handled, the current goroutine will -// be the newly created goroutine. -type GoroutineCreate struct { - commonEvent - parent *Goroutine -} - -// Parent returns the goroutine that created this goroutine. May be -// nil if this event is the creation of the first goroutine. -func (e *GoroutineCreate) Parent() *Goroutine { return e.parent } - -func (e *GoroutineCreate) String() string { - // TODO(austin) Include process name - if e.parent == nil { - return fmt.Sprintf("%v created", e.t) - } - return fmt.Sprintf("%v created by %v", e.t, e.parent) -} - -type goroutineExitHook struct { - commonHook -} - -func (h *goroutineExitHook) String() string { return "goroutine exit" } - -// A GoroutineExit event occurs when a Go goroutine exits. -type GoroutineExit struct { - commonEvent -} - -func (e *GoroutineExit) String() string { - // TODO(austin) Include process name - //return fmt.Sprintf("%v exited", e.t); - // For debugging purposes - return fmt.Sprintf("goroutine %#x exited", e.t.g.addr().base) -} diff --git a/libgo/go/exp/ogle/frame.go b/libgo/go/exp/ogle/frame.go deleted file mode 100644 index 1538362bad2..00000000000 --- a/libgo/go/exp/ogle/frame.go +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ogle - -import ( - "debug/gosym" - "debug/proc" - "fmt" - "os" -) - -// A Frame represents a single frame on a remote call stack. -type Frame struct { - // pc is the PC of the next instruction that will execute in - // this frame. For lower frames, this is the instruction - // following the CALL instruction. - pc, sp, fp proc.Word - // The runtime.Stktop of the active stack segment - stk remoteStruct - // The function this stack frame is in - fn *gosym.Func - // The path and line of the CALL or current instruction. Note - // that this differs slightly from the meaning of Frame.pc. - path string - line int - // The inner and outer frames of this frame. outer is filled - // in lazily. - inner, outer *Frame -} - -// newFrame returns the top-most Frame of the given g's thread. -func newFrame(g remoteStruct) (*Frame, os.Error) { - var f *Frame - err := try(func(a aborter) { f = aNewFrame(a, g) }) - return f, err -} - -func aNewFrame(a aborter, g remoteStruct) *Frame { - p := g.r.p - var pc, sp proc.Word - - // Is this G alive? - switch g.field(p.f.G.Status).(remoteInt).aGet(a) { - case p.runtime.Gidle, p.runtime.Gmoribund, p.runtime.Gdead: - return nil - } - - // Find the OS thread for this G - - // TODO(austin) Ideally, we could look at the G's state and - // figure out if it's on an OS thread or not. However, this - // is difficult because the state isn't updated atomically - // with scheduling changes. - for _, t := range p.proc.Threads() { - regs, err := t.Regs() - if err != nil { - // TODO(austin) What to do? - continue - } - thisg := p.G(regs) - if thisg == g.addr().base { - // Found this G's OS thread - pc = regs.PC() - sp = regs.SP() - - // If this thread crashed, try to recover it - if pc == 0 { - pc = p.peekUintptr(a, pc) - sp += 8 - } - - break - } - } - - if pc == 0 && sp == 0 { - // G is not mapped to an OS thread. Use the - // scheduler's stored PC and SP. - sched := g.field(p.f.G.Sched).(remoteStruct) - pc = proc.Word(sched.field(p.f.Gobuf.Pc).(remoteUint).aGet(a)) - sp = proc.Word(sched.field(p.f.Gobuf.Sp).(remoteUint).aGet(a)) - } - - // Get Stktop - stk := g.field(p.f.G.Stackbase).(remotePtr).aGet(a).(remoteStruct) - - return prepareFrame(a, pc, sp, stk, nil) -} - -// prepareFrame creates a Frame from the PC and SP within that frame, -// as well as the active stack segment. This function takes care of -// traversing stack breaks and unwinding closures. -func prepareFrame(a aborter, pc, sp proc.Word, stk remoteStruct, inner *Frame) *Frame { - // Based on src/pkg/runtime/amd64/traceback.c:traceback - p := stk.r.p - top := inner == nil - - // Get function - var path string - var line int - var fn *gosym.Func - - for i := 0; i < 100; i++ { - // Traverse segmented stack breaks - if p.sys.lessstack != nil && pc == proc.Word(p.sys.lessstack.Value) { - // Get stk->gobuf.pc - pc = proc.Word(stk.field(p.f.Stktop.Gobuf).(remoteStruct).field(p.f.Gobuf.Pc).(remoteUint).aGet(a)) - // Get stk->gobuf.sp - sp = proc.Word(stk.field(p.f.Stktop.Gobuf).(remoteStruct).field(p.f.Gobuf.Sp).(remoteUint).aGet(a)) - // Get stk->stackbase - stk = stk.field(p.f.Stktop.Stackbase).(remotePtr).aGet(a).(remoteStruct) - continue - } - - // Get the PC of the call instruction - callpc := pc - if !top && (p.sys.goexit == nil || pc != proc.Word(p.sys.goexit.Value)) { - callpc-- - } - - // Look up function - path, line, fn = p.syms.PCToLine(uint64(callpc)) - if fn != nil { - break - } - - // Closure? - var buf = make([]byte, p.ClosureSize()) - if _, err := p.Peek(pc, buf); err != nil { - break - } - spdelta, ok := p.ParseClosure(buf) - if ok { - sp += proc.Word(spdelta) - pc = p.peekUintptr(a, sp-proc.Word(p.PtrSize())) - } - } - if fn == nil { - return nil - } - - // Compute frame pointer - var fp proc.Word - if fn.FrameSize < p.PtrSize() { - fp = sp + proc.Word(p.PtrSize()) - } else { - fp = sp + proc.Word(fn.FrameSize) - } - // TODO(austin) To really figure out if we're in the prologue, - // we need to disassemble the function and look for the call - // to morestack. For now, just special case the entry point. - // - // TODO(austin) What if we're in the call to morestack in the - // prologue? Then top == false. - if top && pc == proc.Word(fn.Entry) { - // We're in the function prologue, before SP - // has been adjusted for the frame. - fp -= proc.Word(fn.FrameSize - p.PtrSize()) - } - - return &Frame{pc, sp, fp, stk, fn, path, line, inner, nil} -} - -// Outer returns the Frame that called this Frame, or nil if this is -// the outermost frame. -func (f *Frame) Outer() (*Frame, os.Error) { - var fr *Frame - err := try(func(a aborter) { fr = f.aOuter(a) }) - return fr, err -} - -func (f *Frame) aOuter(a aborter) *Frame { - // Is there a cached outer frame - if f.outer != nil { - return f.outer - } - - p := f.stk.r.p - - sp := f.fp - if f.fn == p.sys.newproc && f.fn == p.sys.deferproc { - // TODO(rsc) The compiler inserts two push/pop's - // around calls to go and defer. Russ says this - // should get fixed in the compiler, but we account - // for it for now. - sp += proc.Word(2 * p.PtrSize()) - } - - pc := p.peekUintptr(a, f.fp-proc.Word(p.PtrSize())) - if pc < 0x1000 { - return nil - } - - // TODO(austin) Register this frame for shoot-down. - - f.outer = prepareFrame(a, pc, sp, f.stk, f) - return f.outer -} - -// Inner returns the Frame called by this Frame, or nil if this is the -// innermost frame. -func (f *Frame) Inner() *Frame { return f.inner } - -func (f *Frame) String() string { - res := f.fn.Name - if f.pc > proc.Word(f.fn.Value) { - res += fmt.Sprintf("+%#x", f.pc-proc.Word(f.fn.Entry)) - } - return res + fmt.Sprintf(" %s:%d", f.path, f.line) -} diff --git a/libgo/go/exp/ogle/goroutine.go b/libgo/go/exp/ogle/goroutine.go deleted file mode 100644 index 5104ec6d479..00000000000 --- a/libgo/go/exp/ogle/goroutine.go +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ogle - -import ( - "debug/proc" - "exp/eval" - "fmt" - "os" -) - -// A Goroutine represents a goroutine in a remote process. -type Goroutine struct { - g remoteStruct - frame *Frame - dead bool -} - -func (t *Goroutine) String() string { - if t.dead { - return "<dead thread>" - } - // TODO(austin) Give threads friendly ID's, possibly including - // the name of the entry function. - return fmt.Sprintf("thread %#x", t.g.addr().base) -} - -// isG0 returns true if this thread if the internal idle thread -func (t *Goroutine) isG0() bool { return t.g.addr().base == t.g.r.p.sys.g0.addr().base } - -func (t *Goroutine) resetFrame() (err os.Error) { - // TODO(austin) Reuse any live part of the current frame stack - // so existing references to Frame's keep working. - t.frame, err = newFrame(t.g) - return -} - -// Out selects the caller frame of the current frame. -func (t *Goroutine) Out() os.Error { - f, err := t.frame.Outer() - if f != nil { - t.frame = f - } - return err -} - -// In selects the frame called by the current frame. -func (t *Goroutine) In() os.Error { - f := t.frame.Inner() - if f != nil { - t.frame = f - } - return nil -} - -func readylockedBP(ev Event) (EventAction, os.Error) { - b := ev.(*Breakpoint) - p := b.Process() - - // The new g is the only argument to this function, so the - // stack will have the return address, then the G*. - regs, err := b.osThread.Regs() - if err != nil { - return EAStop, err - } - sp := regs.SP() - addr := sp + proc.Word(p.PtrSize()) - arg := remotePtr{remote{addr, p}, p.runtime.G} - var gp eval.Value - err = try(func(a aborter) { gp = arg.aGet(a) }) - if err != nil { - return EAStop, err - } - if gp == nil { - return EAStop, UnknownGoroutine{b.osThread, 0} - } - gs := gp.(remoteStruct) - g := &Goroutine{gs, nil, false} - p.goroutines[gs.addr().base] = g - - // Enqueue goroutine creation event - parent := b.Goroutine() - if parent.isG0() { - parent = nil - } - p.postEvent(&GoroutineCreate{commonEvent{p, g}, parent}) - - // If we don't have any thread selected, select this one - if p.curGoroutine == nil { - p.curGoroutine = g - } - - return EADefault, nil -} - -func goexitBP(ev Event) (EventAction, os.Error) { - b := ev.(*Breakpoint) - p := b.Process() - - g := b.Goroutine() - g.dead = true - - addr := g.g.addr().base - p.goroutines[addr] = nil, false - - // Enqueue thread exit event - p.postEvent(&GoroutineExit{commonEvent{p, g}}) - - // If we just exited our selected goroutine, selected another - if p.curGoroutine == g { - p.selectSomeGoroutine() - } - - return EADefault, nil -} diff --git a/libgo/go/exp/ogle/main.go b/libgo/go/exp/ogle/main.go deleted file mode 100644 index 1999ecccab8..00000000000 --- a/libgo/go/exp/ogle/main.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "exp/ogle" - -func main() { ogle.Main() } diff --git a/libgo/go/exp/ogle/process.go b/libgo/go/exp/ogle/process.go deleted file mode 100644 index 7c803b3a27e..00000000000 --- a/libgo/go/exp/ogle/process.go +++ /dev/null @@ -1,521 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ogle - -import ( - "debug/elf" - "debug/gosym" - "debug/proc" - "exp/eval" - "fmt" - "log" - "os" - "reflect" -) - -// A FormatError indicates a failure to process information in or -// about a remote process, such as unexpected or missing information -// in the object file or runtime structures. -type FormatError string - -func (e FormatError) String() string { return string(e) } - -// An UnknownArchitecture occurs when trying to load an object file -// that indicates an architecture not supported by the debugger. -type UnknownArchitecture elf.Machine - -func (e UnknownArchitecture) String() string { - return "unknown architecture: " + elf.Machine(e).String() -} - -// A ProcessNotStopped error occurs when attempting to read or write -// memory or registers of a process that is not stopped. -type ProcessNotStopped struct{} - -func (e ProcessNotStopped) String() string { return "process not stopped" } - -// An UnknownGoroutine error is an internal error representing an -// unrecognized G structure pointer. -type UnknownGoroutine struct { - OSThread proc.Thread - Goroutine proc.Word -} - -func (e UnknownGoroutine) String() string { - return fmt.Sprintf("internal error: unknown goroutine (G %#x)", e.Goroutine) -} - -// A NoCurrentGoroutine error occurs when no goroutine is currently -// selected in a process (or when there are no goroutines in a -// process). -type NoCurrentGoroutine struct{} - -func (e NoCurrentGoroutine) String() string { return "no current goroutine" } - -// A Process represents a remote attached process. -type Process struct { - Arch - proc proc.Process - - // The symbol table of this process - syms *gosym.Table - - // A possibly-stopped OS thread, or nil - threadCache proc.Thread - - // Types parsed from the remote process - types map[proc.Word]*remoteType - - // Types and values from the remote runtime package - runtime runtimeValues - - // Runtime field indexes - f runtimeIndexes - - // Globals from the sys package (or from no package) - sys struct { - lessstack, goexit, newproc, deferproc, newprocreadylocked *gosym.Func - allg remotePtr - g0 remoteStruct - } - - // Event queue - posted []Event - pending []Event - event Event - - // Event hooks - breakpointHooks map[proc.Word]*breakpointHook - goroutineCreateHook *goroutineCreateHook - goroutineExitHook *goroutineExitHook - - // Current goroutine, or nil if there are no goroutines - curGoroutine *Goroutine - - // Goroutines by the address of their G structure - goroutines map[proc.Word]*Goroutine -} - -/* - * Process creation - */ - -// NewProcess constructs a new remote process around a traced -// process, an architecture, and a symbol table. -func NewProcess(tproc proc.Process, arch Arch, syms *gosym.Table) (*Process, os.Error) { - p := &Process{ - Arch: arch, - proc: tproc, - syms: syms, - types: make(map[proc.Word]*remoteType), - breakpointHooks: make(map[proc.Word]*breakpointHook), - goroutineCreateHook: new(goroutineCreateHook), - goroutineExitHook: new(goroutineExitHook), - goroutines: make(map[proc.Word]*Goroutine), - } - - // Fill in remote runtime - p.bootstrap() - - switch { - case p.sys.allg.addr().base == 0: - return nil, FormatError("failed to find runtime symbol 'allg'") - case p.sys.g0.addr().base == 0: - return nil, FormatError("failed to find runtime symbol 'g0'") - case p.sys.newprocreadylocked == nil: - return nil, FormatError("failed to find runtime symbol 'newprocreadylocked'") - case p.sys.goexit == nil: - return nil, FormatError("failed to find runtime symbol 'sys.goexit'") - } - - // Get current goroutines - p.goroutines[p.sys.g0.addr().base] = &Goroutine{p.sys.g0, nil, false} - err := try(func(a aborter) { - g := p.sys.allg.aGet(a) - for g != nil { - gs := g.(remoteStruct) - fmt.Printf("*** Found goroutine at %#x\n", gs.addr().base) - p.goroutines[gs.addr().base] = &Goroutine{gs, nil, false} - g = gs.field(p.f.G.Alllink).(remotePtr).aGet(a) - } - }) - if err != nil { - return nil, err - } - - // Create internal breakpoints to catch new and exited goroutines - p.OnBreakpoint(proc.Word(p.sys.newprocreadylocked.Entry)).(*breakpointHook).addHandler(readylockedBP, true) - p.OnBreakpoint(proc.Word(p.sys.goexit.Entry)).(*breakpointHook).addHandler(goexitBP, true) - - // Select current frames - for _, g := range p.goroutines { - g.resetFrame() - } - - p.selectSomeGoroutine() - - return p, nil -} - -func elfGoSyms(f *elf.File) (*gosym.Table, os.Error) { - text := f.Section(".text") - symtab := f.Section(".gosymtab") - pclntab := f.Section(".gopclntab") - if text == nil || symtab == nil || pclntab == nil { - return nil, nil - } - - symdat, err := symtab.Data() - if err != nil { - return nil, err - } - pclndat, err := pclntab.Data() - if err != nil { - return nil, err - } - - pcln := gosym.NewLineTable(pclndat, text.Addr) - tab, err := gosym.NewTable(symdat, pcln) - if err != nil { - return nil, err - } - - return tab, nil -} - -// NewProcessElf constructs a new remote process around a traced -// process and the process' ELF object. -func NewProcessElf(tproc proc.Process, f *elf.File) (*Process, os.Error) { - syms, err := elfGoSyms(f) - if err != nil { - return nil, err - } - if syms == nil { - return nil, FormatError("Failed to find symbol table") - } - var arch Arch - switch f.Machine { - case elf.EM_X86_64: - arch = Amd64 - default: - return nil, UnknownArchitecture(f.Machine) - } - return NewProcess(tproc, arch, syms) -} - -// bootstrap constructs the runtime structure of a remote process. -func (p *Process) bootstrap() { - // Manually construct runtime types - p.runtime.String = newManualType(eval.TypeOfNative(rt1String{}), p.Arch) - p.runtime.Slice = newManualType(eval.TypeOfNative(rt1Slice{}), p.Arch) - p.runtime.Eface = newManualType(eval.TypeOfNative(rt1Eface{}), p.Arch) - - p.runtime.Type = newManualType(eval.TypeOfNative(rt1Type{}), p.Arch) - p.runtime.CommonType = newManualType(eval.TypeOfNative(rt1CommonType{}), p.Arch) - p.runtime.UncommonType = newManualType(eval.TypeOfNative(rt1UncommonType{}), p.Arch) - p.runtime.StructField = newManualType(eval.TypeOfNative(rt1StructField{}), p.Arch) - p.runtime.StructType = newManualType(eval.TypeOfNative(rt1StructType{}), p.Arch) - p.runtime.PtrType = newManualType(eval.TypeOfNative(rt1PtrType{}), p.Arch) - p.runtime.ArrayType = newManualType(eval.TypeOfNative(rt1ArrayType{}), p.Arch) - p.runtime.SliceType = newManualType(eval.TypeOfNative(rt1SliceType{}), p.Arch) - - p.runtime.Stktop = newManualType(eval.TypeOfNative(rt1Stktop{}), p.Arch) - p.runtime.Gobuf = newManualType(eval.TypeOfNative(rt1Gobuf{}), p.Arch) - p.runtime.G = newManualType(eval.TypeOfNative(rt1G{}), p.Arch) - - // Get addresses of type.*runtime.XType for discrimination. - rtv := reflect.Indirect(reflect.ValueOf(&p.runtime)) - rtvt := rtv.Type() - for i := 0; i < rtv.NumField(); i++ { - n := rtvt.Field(i).Name - if n[0] != 'P' || n[1] < 'A' || n[1] > 'Z' { - continue - } - sym := p.syms.LookupSym("type.*runtime." + n[1:]) - if sym == nil { - continue - } - rtv.Field(i).SetUint(sym.Value) - } - - // Get runtime field indexes - fillRuntimeIndexes(&p.runtime, &p.f) - - // Fill G status - p.runtime.runtimeGStatus = rt1GStatus - - // Get globals - p.sys.lessstack = p.syms.LookupFunc("sys.lessstack") - p.sys.goexit = p.syms.LookupFunc("goexit") - p.sys.newproc = p.syms.LookupFunc("sys.newproc") - p.sys.deferproc = p.syms.LookupFunc("sys.deferproc") - p.sys.newprocreadylocked = p.syms.LookupFunc("newprocreadylocked") - if allg := p.syms.LookupSym("allg"); allg != nil { - p.sys.allg = remotePtr{remote{proc.Word(allg.Value), p}, p.runtime.G} - } - if g0 := p.syms.LookupSym("g0"); g0 != nil { - p.sys.g0 = p.runtime.G.mk(remote{proc.Word(g0.Value), p}).(remoteStruct) - } -} - -func (p *Process) selectSomeGoroutine() { - // Once we have friendly goroutine ID's, there might be a more - // reasonable behavior for this. - p.curGoroutine = nil - for _, g := range p.goroutines { - if !g.isG0() && g.frame != nil { - p.curGoroutine = g - return - } - } -} - -/* - * Process memory - */ - -func (p *Process) someStoppedOSThread() proc.Thread { - if p.threadCache != nil { - if _, err := p.threadCache.Stopped(); err == nil { - return p.threadCache - } - } - - for _, t := range p.proc.Threads() { - if _, err := t.Stopped(); err == nil { - p.threadCache = t - return t - } - } - return nil -} - -func (p *Process) Peek(addr proc.Word, out []byte) (int, os.Error) { - thr := p.someStoppedOSThread() - if thr == nil { - return 0, ProcessNotStopped{} - } - return thr.Peek(addr, out) -} - -func (p *Process) Poke(addr proc.Word, b []byte) (int, os.Error) { - thr := p.someStoppedOSThread() - if thr == nil { - return 0, ProcessNotStopped{} - } - return thr.Poke(addr, b) -} - -func (p *Process) peekUintptr(a aborter, addr proc.Word) proc.Word { - return proc.Word(mkUintptr(remote{addr, p}).(remoteUint).aGet(a)) -} - -/* - * Events - */ - -// OnBreakpoint returns the hook that is run when the program reaches -// the given program counter. -func (p *Process) OnBreakpoint(pc proc.Word) EventHook { - if bp, ok := p.breakpointHooks[pc]; ok { - return bp - } - // The breakpoint will register itself when a handler is added - return &breakpointHook{commonHook{nil, 0}, p, pc} -} - -// OnGoroutineCreate returns the hook that is run when a goroutine is created. -func (p *Process) OnGoroutineCreate() EventHook { - return p.goroutineCreateHook -} - -// OnGoroutineExit returns the hook that is run when a goroutine exits. -func (p *Process) OnGoroutineExit() EventHook { return p.goroutineExitHook } - -// osThreadToGoroutine looks up the goroutine running on an OS thread. -func (p *Process) osThreadToGoroutine(t proc.Thread) (*Goroutine, os.Error) { - regs, err := t.Regs() - if err != nil { - return nil, err - } - g := p.G(regs) - gt, ok := p.goroutines[g] - if !ok { - return nil, UnknownGoroutine{t, g} - } - return gt, nil -} - -// causesToEvents translates the stop causes of the underlying process -// into an event queue. -func (p *Process) causesToEvents() ([]Event, os.Error) { - // Count causes we're interested in - nev := 0 - for _, t := range p.proc.Threads() { - if c, err := t.Stopped(); err == nil { - switch c := c.(type) { - case proc.Breakpoint: - nev++ - case proc.Signal: - // TODO(austin) - //nev++; - } - } - } - - // Translate causes to events - events := make([]Event, nev) - i := 0 - for _, t := range p.proc.Threads() { - if c, err := t.Stopped(); err == nil { - switch c := c.(type) { - case proc.Breakpoint: - gt, err := p.osThreadToGoroutine(t) - if err != nil { - return nil, err - } - events[i] = &Breakpoint{commonEvent{p, gt}, t, proc.Word(c)} - i++ - case proc.Signal: - // TODO(austin) - } - } - } - - return events, nil -} - -// postEvent appends an event to the posted queue. These events will -// be processed before any currently pending events. -func (p *Process) postEvent(ev Event) { - p.posted = append(p.posted, ev) -} - -// processEvents processes events in the event queue until no events -// remain, a handler returns EAStop, or a handler returns an error. -// It returns either EAStop or EAContinue and possibly an error. -func (p *Process) processEvents() (EventAction, os.Error) { - var ev Event - for len(p.posted) > 0 { - ev, p.posted = p.posted[0], p.posted[1:] - action, err := p.processEvent(ev) - if action == EAStop { - return action, err - } - } - - for len(p.pending) > 0 { - ev, p.pending = p.pending[0], p.pending[1:] - action, err := p.processEvent(ev) - if action == EAStop { - return action, err - } - } - - return EAContinue, nil -} - -// processEvent processes a single event, without manipulating the -// event queues. It returns either EAStop or EAContinue and possibly -// an error. -func (p *Process) processEvent(ev Event) (EventAction, os.Error) { - p.event = ev - - var action EventAction - var err os.Error - switch ev := p.event.(type) { - case *Breakpoint: - hook, ok := p.breakpointHooks[ev.pc] - if !ok { - break - } - p.curGoroutine = ev.Goroutine() - action, err = hook.handle(ev) - - case *GoroutineCreate: - p.curGoroutine = ev.Goroutine() - action, err = p.goroutineCreateHook.handle(ev) - - case *GoroutineExit: - action, err = p.goroutineExitHook.handle(ev) - - default: - log.Panicf("Unknown event type %T in queue", p.event) - } - - if err != nil { - return EAStop, err - } else if action == EAStop { - return EAStop, nil - } - return EAContinue, nil -} - -// Event returns the last event that caused the process to stop. This -// may return nil if the process has never been stopped by an event. -// -// TODO(austin) Return nil if the user calls p.Stop()? -func (p *Process) Event() Event { return p.event } - -/* - * Process control - */ - -// TODO(austin) Cont, WaitStop, and Stop. Need to figure out how -// event handling works with these. Originally I did it only in -// WaitStop, but if you Cont and there are pending events, then you -// have to not actually continue and wait until a WaitStop to process -// them, even if the event handlers will tell you to continue. We -// could handle them in both Cont and WaitStop to avoid this problem, -// but it's still weird if an event happens after the Cont and before -// the WaitStop that the handlers say to continue from. Or we could -// handle them on a separate thread. Then obviously you get weird -// asynchronous things, like prints while the user it typing a command, -// but that's not necessarily a bad thing. - -// ContWait resumes process execution and waits for an event to occur -// that stops the process. -func (p *Process) ContWait() os.Error { - for { - a, err := p.processEvents() - if err != nil { - return err - } else if a == EAStop { - break - } - err = p.proc.Continue() - if err != nil { - return err - } - err = p.proc.WaitStop() - if err != nil { - return err - } - for _, g := range p.goroutines { - g.resetFrame() - } - p.pending, err = p.causesToEvents() - if err != nil { - return err - } - } - return nil -} - -// Out selects the caller frame of the current frame. -func (p *Process) Out() os.Error { - if p.curGoroutine == nil { - return NoCurrentGoroutine{} - } - return p.curGoroutine.Out() -} - -// In selects the frame called by the current frame. -func (p *Process) In() os.Error { - if p.curGoroutine == nil { - return NoCurrentGoroutine{} - } - return p.curGoroutine.In() -} diff --git a/libgo/go/exp/ogle/rruntime.go b/libgo/go/exp/ogle/rruntime.go deleted file mode 100644 index 950418b5388..00000000000 --- a/libgo/go/exp/ogle/rruntime.go +++ /dev/null @@ -1,271 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ogle - -import ( - "debug/proc" - "exp/eval" - "reflect" -) - -// This file contains remote runtime definitions. Using reflection, -// we convert all of these to interpreter types and layout their -// remote representations using the architecture rules. -// -// We could get most of these definitions from our own runtime -// package; however, some of them differ in convenient ways, some of -// them are not defined or exported by the runtime, and having our own -// definitions makes it easy to support multiple remote runtime -// versions. This may turn out to be overkill. -// -// All of these structures are prefixed with rt1 to indicate the -// runtime version and to mark them as types used only as templates -// for remote types. - -/* - * Runtime data headers - * - * See $GOROOT/src/pkg/runtime/runtime.h - */ - -type rt1String struct { - str uintptr - len int -} - -type rt1Slice struct { - array uintptr - len int - cap int -} - -type rt1Eface struct { - typ uintptr - ptr uintptr -} - -/* - * Runtime type structures - * - * See $GOROOT/src/pkg/runtime/type.h and $GOROOT/src/pkg/runtime/type.go - */ - -type rt1UncommonType struct { - name *string - pkgPath *string - //methods []method; -} - -type rt1CommonType struct { - size uintptr - hash uint32 - alg, align, fieldAlign uint8 - string *string - uncommonType *rt1UncommonType -} - -type rt1Type struct { - // While Type is technically an Eface, treating the - // discriminator as an opaque pointer and taking advantage of - // the commonType prologue on all Type's makes type parsing - // much simpler. - typ uintptr - ptr *rt1CommonType -} - -type rt1StructField struct { - name *string - pkgPath *string - typ *rt1Type - tag *string - offset uintptr -} - -type rt1StructType struct { - rt1CommonType - fields []rt1StructField -} - -type rt1PtrType struct { - rt1CommonType - elem *rt1Type -} - -type rt1SliceType struct { - rt1CommonType - elem *rt1Type -} - -type rt1ArrayType struct { - rt1CommonType - elem *rt1Type - len uintptr -} - -/* - * Runtime scheduler structures - * - * See $GOROOT/src/pkg/runtime/runtime.h - */ - -// Fields beginning with _ are only for padding - -type rt1Stktop struct { - stackguard uintptr - stackbase *rt1Stktop - gobuf rt1Gobuf - _args uint32 - _fp uintptr -} - -type rt1Gobuf struct { - sp uintptr - pc uintptr - g *rt1G - r0 uintptr -} - -type rt1G struct { - _stackguard uintptr - stackbase *rt1Stktop - _defer uintptr - sched rt1Gobuf - _stack0 uintptr - _entry uintptr - alllink *rt1G - _param uintptr - status int16 - // Incomplete -} - -var rt1GStatus = runtimeGStatus{ - Gidle: 0, - Grunnable: 1, - Grunning: 2, - Gsyscall: 3, - Gwaiting: 4, - Gmoribund: 5, - Gdead: 6, -} - -// runtimeIndexes stores the indexes of fields in the runtime -// structures. It is filled in using reflection, so the name of the -// fields must match the names of the remoteType's in runtimeValues -// exactly and the names of the index fields must be the capitalized -// version of the names of the fields in the runtime structures above. -type runtimeIndexes struct { - String struct { - Str, Len int - } - Slice struct { - Array, Len, Cap int - } - Eface struct { - Typ, Ptr int - } - - UncommonType struct { - Name, PkgPath int - } - CommonType struct { - Size, Hash, Alg, Align, FieldAlign, String, UncommonType int - } - Type struct { - Typ, Ptr int - } - StructField struct { - Name, PkgPath, Typ, Tag, Offset int - } - StructType struct { - Fields int - } - PtrType struct { - Elem int - } - SliceType struct { - Elem int - } - ArrayType struct { - Elem, Len int - } - - Stktop struct { - Stackguard, Stackbase, Gobuf int - } - Gobuf struct { - Sp, Pc, G int - } - G struct { - Stackbase, Sched, Status, Alllink int - } -} - -// Values of G status codes -type runtimeGStatus struct { - Gidle, Grunnable, Grunning, Gsyscall, Gwaiting, Gmoribund, Gdead int64 -} - -// runtimeValues stores the types and values that correspond to those -// in the remote runtime package. -type runtimeValues struct { - // Runtime data headers - String, Slice, Eface *remoteType - // Runtime type structures - Type, CommonType, UncommonType, StructField, StructType, PtrType, - ArrayType, SliceType *remoteType - // Runtime scheduler structures - Stktop, Gobuf, G *remoteType - // Addresses of *runtime.XType types. These are the - // discriminators on the runtime.Type interface. We use local - // reflection to fill these in from the remote symbol table, - // so the names must match the runtime names. - PBoolType, - PUint8Type, PUint16Type, PUint32Type, PUint64Type, PUintType, PUintptrType, - PInt8Type, PInt16Type, PInt32Type, PInt64Type, PIntType, - PFloat32Type, PFloat64Type, PFloatType, - PArrayType, PStringType, PStructType, PPtrType, PFuncType, - PInterfaceType, PSliceType, PMapType, PChanType, - PDotDotDotType, PUnsafePointerType proc.Word - // G status values - runtimeGStatus -} - -// fillRuntimeIndexes fills a runtimeIndexes structure will the field -// indexes gathered from the remoteTypes recorded in a runtimeValues -// structure. -func fillRuntimeIndexes(runtime *runtimeValues, out *runtimeIndexes) { - outv := reflect.Indirect(reflect.ValueOf(out)) - outt := outv.Type() - runtimev := reflect.Indirect(reflect.ValueOf(runtime)) - - // out contains fields corresponding to each runtime type - for i := 0; i < outt.NumField(); i++ { - // Find the interpreter type for this runtime type - name := outt.Field(i).Name - et := runtimev.FieldByName(name).Interface().(*remoteType).Type.(*eval.StructType) - - // Get the field indexes of the interpreter struct type - indexes := make(map[string]int, len(et.Elems)) - for j, f := range et.Elems { - if f.Anonymous { - continue - } - name := f.Name - if name[0] >= 'a' && name[0] <= 'z' { - name = string(name[0]+'A'-'a') + name[1:] - } - indexes[name] = j - } - - // Fill this field of out - outStructv := outv.Field(i) - outStructt := outStructv.Type() - for j := 0; j < outStructt.NumField(); j++ { - f := outStructv.Field(j) - name := outStructt.Field(j).Name - f.SetInt(int64(indexes[name])) - } - } -} diff --git a/libgo/go/exp/ogle/rtype.go b/libgo/go/exp/ogle/rtype.go deleted file mode 100644 index b3c35575af4..00000000000 --- a/libgo/go/exp/ogle/rtype.go +++ /dev/null @@ -1,288 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ogle - -import ( - "debug/proc" - "exp/eval" - "fmt" - "log" -) - -const debugParseRemoteType = false - -// A remoteType is the local representation of a type in a remote process. -type remoteType struct { - eval.Type - // The size of values of this type in bytes. - size int - // The field alignment of this type. Only used for - // manually-constructed types. - fieldAlign int - // The maker function to turn a remote address of a value of - // this type into an interpreter Value. - mk maker -} - -var manualTypes = make(map[Arch]map[eval.Type]*remoteType) - -// newManualType constructs a remote type from an interpreter Type -// using the size and alignment properties of the given architecture. -// Most types are parsed directly out of the remote process, but to do -// so we need to layout the structures that describe those types ourselves. -func newManualType(t eval.Type, arch Arch) *remoteType { - if nt, ok := t.(*eval.NamedType); ok { - t = nt.Def - } - - // Get the type map for this architecture - typeMap := manualTypes[arch] - if typeMap == nil { - typeMap = make(map[eval.Type]*remoteType) - manualTypes[arch] = typeMap - - // Construct basic types for this architecture - basicType := func(t eval.Type, mk maker, size int, fieldAlign int) { - t = t.(*eval.NamedType).Def - if fieldAlign == 0 { - fieldAlign = size - } - typeMap[t] = &remoteType{t, size, fieldAlign, mk} - } - basicType(eval.Uint8Type, mkUint8, 1, 0) - basicType(eval.Uint32Type, mkUint32, 4, 0) - basicType(eval.UintptrType, mkUintptr, arch.PtrSize(), 0) - basicType(eval.Int16Type, mkInt16, 2, 0) - basicType(eval.Int32Type, mkInt32, 4, 0) - basicType(eval.IntType, mkInt, arch.IntSize(), 0) - basicType(eval.StringType, mkString, arch.PtrSize()+arch.IntSize(), arch.PtrSize()) - } - - if rt, ok := typeMap[t]; ok { - return rt - } - - var rt *remoteType - switch t := t.(type) { - case *eval.PtrType: - var elem *remoteType - mk := func(r remote) eval.Value { return remotePtr{r, elem} } - rt = &remoteType{t, arch.PtrSize(), arch.PtrSize(), mk} - // Construct the element type after registering the - // type to break cycles. - typeMap[eval.Type(t)] = rt - elem = newManualType(t.Elem, arch) - - case *eval.ArrayType: - elem := newManualType(t.Elem, arch) - mk := func(r remote) eval.Value { return remoteArray{r, t.Len, elem} } - rt = &remoteType{t, elem.size * int(t.Len), elem.fieldAlign, mk} - - case *eval.SliceType: - elem := newManualType(t.Elem, arch) - mk := func(r remote) eval.Value { return remoteSlice{r, elem} } - rt = &remoteType{t, arch.PtrSize() + 2*arch.IntSize(), arch.PtrSize(), mk} - - case *eval.StructType: - layout := make([]remoteStructField, len(t.Elems)) - offset := 0 - fieldAlign := 0 - for i, f := range t.Elems { - elem := newManualType(f.Type, arch) - if fieldAlign == 0 { - fieldAlign = elem.fieldAlign - } - offset = arch.Align(offset, elem.fieldAlign) - layout[i].offset = offset - layout[i].fieldType = elem - offset += elem.size - } - mk := func(r remote) eval.Value { return remoteStruct{r, layout} } - rt = &remoteType{t, offset, fieldAlign, mk} - - default: - log.Panicf("cannot manually construct type %T", t) - } - - typeMap[t] = rt - return rt -} - -var prtIndent = "" - -// parseRemoteType parses a Type structure in a remote process to -// construct the corresponding interpreter type and remote type. -func parseRemoteType(a aborter, rs remoteStruct) *remoteType { - addr := rs.addr().base - p := rs.addr().p - - // We deal with circular types by discovering cycles at - // NamedTypes. If a type cycles back to something other than - // a named type, we're guaranteed that there will be a named - // type somewhere in that cycle. Thus, we continue down, - // re-parsing types until we reach the named type in the - // cycle. In order to still create one remoteType per remote - // type, we insert an empty remoteType in the type map the - // first time we encounter the type and re-use that structure - // the second time we encounter it. - - rt, ok := p.types[addr] - if ok && rt.Type != nil { - return rt - } else if !ok { - rt = &remoteType{} - p.types[addr] = rt - } - - if debugParseRemoteType { - sym := p.syms.SymByAddr(uint64(addr)) - name := "<unknown>" - if sym != nil { - name = sym.Name - } - log.Printf("%sParsing type at %#x (%s)", prtIndent, addr, name) - prtIndent += " " - defer func() { prtIndent = prtIndent[0 : len(prtIndent)-1] }() - } - - // Get Type header - itype := proc.Word(rs.field(p.f.Type.Typ).(remoteUint).aGet(a)) - typ := rs.field(p.f.Type.Ptr).(remotePtr).aGet(a).(remoteStruct) - - // Is this a named type? - var nt *eval.NamedType - uncommon := typ.field(p.f.CommonType.UncommonType).(remotePtr).aGet(a) - if uncommon != nil { - name := uncommon.(remoteStruct).field(p.f.UncommonType.Name).(remotePtr).aGet(a) - if name != nil { - // TODO(austin) Declare type in appropriate remote package - nt = eval.NewNamedType(name.(remoteString).aGet(a)) - rt.Type = nt - } - } - - // Create type - var t eval.Type - var mk maker - switch itype { - case p.runtime.PBoolType: - t = eval.BoolType - mk = mkBool - case p.runtime.PUint8Type: - t = eval.Uint8Type - mk = mkUint8 - case p.runtime.PUint16Type: - t = eval.Uint16Type - mk = mkUint16 - case p.runtime.PUint32Type: - t = eval.Uint32Type - mk = mkUint32 - case p.runtime.PUint64Type: - t = eval.Uint64Type - mk = mkUint64 - case p.runtime.PUintType: - t = eval.UintType - mk = mkUint - case p.runtime.PUintptrType: - t = eval.UintptrType - mk = mkUintptr - case p.runtime.PInt8Type: - t = eval.Int8Type - mk = mkInt8 - case p.runtime.PInt16Type: - t = eval.Int16Type - mk = mkInt16 - case p.runtime.PInt32Type: - t = eval.Int32Type - mk = mkInt32 - case p.runtime.PInt64Type: - t = eval.Int64Type - mk = mkInt64 - case p.runtime.PIntType: - t = eval.IntType - mk = mkInt - case p.runtime.PFloat32Type: - t = eval.Float32Type - mk = mkFloat32 - case p.runtime.PFloat64Type: - t = eval.Float64Type - mk = mkFloat64 - case p.runtime.PStringType: - t = eval.StringType - mk = mkString - - case p.runtime.PArrayType: - // Cast to an ArrayType - typ := p.runtime.ArrayType.mk(typ.addr()).(remoteStruct) - len := int64(typ.field(p.f.ArrayType.Len).(remoteUint).aGet(a)) - elem := parseRemoteType(a, typ.field(p.f.ArrayType.Elem).(remotePtr).aGet(a).(remoteStruct)) - t = eval.NewArrayType(len, elem.Type) - mk = func(r remote) eval.Value { return remoteArray{r, len, elem} } - - case p.runtime.PStructType: - // Cast to a StructType - typ := p.runtime.StructType.mk(typ.addr()).(remoteStruct) - fs := typ.field(p.f.StructType.Fields).(remoteSlice).aGet(a) - - fields := make([]eval.StructField, fs.Len) - layout := make([]remoteStructField, fs.Len) - for i := range fields { - f := fs.Base.(remoteArray).elem(int64(i)).(remoteStruct) - elemrs := f.field(p.f.StructField.Typ).(remotePtr).aGet(a).(remoteStruct) - elem := parseRemoteType(a, elemrs) - fields[i].Type = elem.Type - name := f.field(p.f.StructField.Name).(remotePtr).aGet(a) - if name == nil { - fields[i].Anonymous = true - } else { - fields[i].Name = name.(remoteString).aGet(a) - } - layout[i].offset = int(f.field(p.f.StructField.Offset).(remoteUint).aGet(a)) - layout[i].fieldType = elem - } - - t = eval.NewStructType(fields) - mk = func(r remote) eval.Value { return remoteStruct{r, layout} } - - case p.runtime.PPtrType: - // Cast to a PtrType - typ := p.runtime.PtrType.mk(typ.addr()).(remoteStruct) - elem := parseRemoteType(a, typ.field(p.f.PtrType.Elem).(remotePtr).aGet(a).(remoteStruct)) - t = eval.NewPtrType(elem.Type) - mk = func(r remote) eval.Value { return remotePtr{r, elem} } - - case p.runtime.PSliceType: - // Cast to a SliceType - typ := p.runtime.SliceType.mk(typ.addr()).(remoteStruct) - elem := parseRemoteType(a, typ.field(p.f.SliceType.Elem).(remotePtr).aGet(a).(remoteStruct)) - t = eval.NewSliceType(elem.Type) - mk = func(r remote) eval.Value { return remoteSlice{r, elem} } - - case p.runtime.PMapType, p.runtime.PChanType, p.runtime.PFuncType, p.runtime.PInterfaceType, p.runtime.PUnsafePointerType, p.runtime.PDotDotDotType: - // TODO(austin) - t = eval.UintptrType - mk = mkUintptr - - default: - sym := p.syms.SymByAddr(uint64(itype)) - name := "<unknown symbol>" - if sym != nil { - name = sym.Name - } - err := fmt.Sprintf("runtime type at %#x has unexpected type %#x (%s)", addr, itype, name) - a.Abort(FormatError(err)) - } - - // Fill in the remote type - if nt != nil { - nt.Complete(t) - } else { - rt.Type = t - } - rt.size = int(typ.field(p.f.CommonType.Size).(remoteUint).aGet(a)) - rt.mk = mk - - return rt -} diff --git a/libgo/go/exp/ogle/rvalue.go b/libgo/go/exp/ogle/rvalue.go deleted file mode 100644 index 3d630f93664..00000000000 --- a/libgo/go/exp/ogle/rvalue.go +++ /dev/null @@ -1,515 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ogle - -import ( - "debug/proc" - "exp/eval" - "fmt" -) - -// A RemoteMismatchError occurs when an operation that requires two -// identical remote processes is given different process. For -// example, this occurs when trying to set a pointer in one process to -// point to something in another process. -type RemoteMismatchError string - -func (e RemoteMismatchError) String() string { return string(e) } - -// A ReadOnlyError occurs when attempting to set or assign to a -// read-only value. -type ReadOnlyError string - -func (e ReadOnlyError) String() string { return string(e) } - -// A maker is a function that converts a remote address into an -// interpreter Value. -type maker func(remote) eval.Value - -type remoteValue interface { - addr() remote -} - -// remote represents an address in a remote process. -type remote struct { - base proc.Word - p *Process -} - -func (v remote) Get(a aborter, size int) uint64 { - // TODO(austin) This variable might temporarily be in a - // register. We could trace the assembly back from the - // current PC, looking for the beginning of the function or a - // call (both of which guarantee that the variable is in - // memory), or an instruction that loads the variable into a - // register. - // - // TODO(austin) If this is a local variable, it might not be - // live at this PC. In fact, because the compiler reuses - // slots, there might even be a different local variable at - // this location right now. A simple solution to both - // problems is to include the range of PC's over which a local - // variable is live in the symbol table. - // - // TODO(austin) We need to prevent the remote garbage - // collector from collecting objects out from under us. - var arr [8]byte - buf := arr[0:size] - _, err := v.p.Peek(v.base, buf) - if err != nil { - a.Abort(err) - } - return uint64(v.p.ToWord(buf)) -} - -func (v remote) Set(a aborter, size int, x uint64) { - var arr [8]byte - buf := arr[0:size] - v.p.FromWord(proc.Word(x), buf) - _, err := v.p.Poke(v.base, buf) - if err != nil { - a.Abort(err) - } -} - -func (v remote) plus(x proc.Word) remote { return remote{v.base + x, v.p} } - -func tryRVString(f func(a aborter) string) string { - var s string - err := try(func(a aborter) { s = f(a) }) - if err != nil { - return fmt.Sprintf("<error: %v>", err) - } - return s -} - -/* - * Bool - */ - -type remoteBool struct { - r remote -} - -func (v remoteBool) String() string { - return tryRVString(func(a aborter) string { return fmt.Sprintf("%v", v.aGet(a)) }) -} - -func (v remoteBool) Assign(t *eval.Thread, o eval.Value) { - v.Set(t, o.(eval.BoolValue).Get(t)) -} - -func (v remoteBool) Get(t *eval.Thread) bool { return v.aGet(t) } - -func (v remoteBool) aGet(a aborter) bool { return v.r.Get(a, 1) != 0 } - -func (v remoteBool) Set(t *eval.Thread, x bool) { - v.aSet(t, x) -} - -func (v remoteBool) aSet(a aborter, x bool) { - if x { - v.r.Set(a, 1, 1) - } else { - v.r.Set(a, 1, 0) - } -} - -func (v remoteBool) addr() remote { return v.r } - -func mkBool(r remote) eval.Value { return remoteBool{r} } - -/* - * Uint - */ - -type remoteUint struct { - r remote - size int -} - -func (v remoteUint) String() string { - return tryRVString(func(a aborter) string { return fmt.Sprintf("%v", v.aGet(a)) }) -} - -func (v remoteUint) Assign(t *eval.Thread, o eval.Value) { - v.Set(t, o.(eval.UintValue).Get(t)) -} - -func (v remoteUint) Get(t *eval.Thread) uint64 { - return v.aGet(t) -} - -func (v remoteUint) aGet(a aborter) uint64 { return v.r.Get(a, v.size) } - -func (v remoteUint) Set(t *eval.Thread, x uint64) { - v.aSet(t, x) -} - -func (v remoteUint) aSet(a aborter, x uint64) { v.r.Set(a, v.size, x) } - -func (v remoteUint) addr() remote { return v.r } - -func mkUint8(r remote) eval.Value { return remoteUint{r, 1} } - -func mkUint16(r remote) eval.Value { return remoteUint{r, 2} } - -func mkUint32(r remote) eval.Value { return remoteUint{r, 4} } - -func mkUint64(r remote) eval.Value { return remoteUint{r, 8} } - -func mkUint(r remote) eval.Value { return remoteUint{r, r.p.IntSize()} } - -func mkUintptr(r remote) eval.Value { return remoteUint{r, r.p.PtrSize()} } - -/* - * Int - */ - -type remoteInt struct { - r remote - size int -} - -func (v remoteInt) String() string { - return tryRVString(func(a aborter) string { return fmt.Sprintf("%v", v.aGet(a)) }) -} - -func (v remoteInt) Assign(t *eval.Thread, o eval.Value) { - v.Set(t, o.(eval.IntValue).Get(t)) -} - -func (v remoteInt) Get(t *eval.Thread) int64 { return v.aGet(t) } - -func (v remoteInt) aGet(a aborter) int64 { return int64(v.r.Get(a, v.size)) } - -func (v remoteInt) Set(t *eval.Thread, x int64) { - v.aSet(t, x) -} - -func (v remoteInt) aSet(a aborter, x int64) { v.r.Set(a, v.size, uint64(x)) } - -func (v remoteInt) addr() remote { return v.r } - -func mkInt8(r remote) eval.Value { return remoteInt{r, 1} } - -func mkInt16(r remote) eval.Value { return remoteInt{r, 2} } - -func mkInt32(r remote) eval.Value { return remoteInt{r, 4} } - -func mkInt64(r remote) eval.Value { return remoteInt{r, 8} } - -func mkInt(r remote) eval.Value { return remoteInt{r, r.p.IntSize()} } - -/* - * Float - */ - -type remoteFloat struct { - r remote - size int -} - -func (v remoteFloat) String() string { - return tryRVString(func(a aborter) string { return fmt.Sprintf("%v", v.aGet(a)) }) -} - -func (v remoteFloat) Assign(t *eval.Thread, o eval.Value) { - v.Set(t, o.(eval.FloatValue).Get(t)) -} - -func (v remoteFloat) Get(t *eval.Thread) float64 { - return v.aGet(t) -} - -func (v remoteFloat) aGet(a aborter) float64 { - bits := v.r.Get(a, v.size) - switch v.size { - case 4: - return float64(v.r.p.ToFloat32(uint32(bits))) - case 8: - return v.r.p.ToFloat64(bits) - } - panic("Unexpected float size") -} - -func (v remoteFloat) Set(t *eval.Thread, x float64) { - v.aSet(t, x) -} - -func (v remoteFloat) aSet(a aborter, x float64) { - var bits uint64 - switch v.size { - case 4: - bits = uint64(v.r.p.FromFloat32(float32(x))) - case 8: - bits = v.r.p.FromFloat64(x) - default: - panic("Unexpected float size") - } - v.r.Set(a, v.size, bits) -} - -func (v remoteFloat) addr() remote { return v.r } - -func mkFloat32(r remote) eval.Value { return remoteFloat{r, 4} } - -func mkFloat64(r remote) eval.Value { return remoteFloat{r, 8} } - -func mkFloat(r remote) eval.Value { return remoteFloat{r, r.p.FloatSize()} } - -/* - * String - */ - -type remoteString struct { - r remote -} - -func (v remoteString) String() string { - return tryRVString(func(a aborter) string { return v.aGet(a) }) -} - -func (v remoteString) Assign(t *eval.Thread, o eval.Value) { - v.Set(t, o.(eval.StringValue).Get(t)) -} - -func (v remoteString) Get(t *eval.Thread) string { - return v.aGet(t) -} - -func (v remoteString) aGet(a aborter) string { - rs := v.r.p.runtime.String.mk(v.r).(remoteStruct) - str := proc.Word(rs.field(v.r.p.f.String.Str).(remoteUint).aGet(a)) - len := rs.field(v.r.p.f.String.Len).(remoteInt).aGet(a) - - bytes := make([]uint8, len) - _, err := v.r.p.Peek(str, bytes) - if err != nil { - a.Abort(err) - } - return string(bytes) -} - -func (v remoteString) Set(t *eval.Thread, x string) { - v.aSet(t, x) -} - -func (v remoteString) aSet(a aborter, x string) { - // TODO(austin) This isn't generally possible without the - // ability to allocate remote memory. - a.Abort(ReadOnlyError("remote strings cannot be assigned to")) -} - -func mkString(r remote) eval.Value { return remoteString{r} } - -/* - * Array - */ - -type remoteArray struct { - r remote - len int64 - elemType *remoteType -} - -func (v remoteArray) String() string { - res := "{" - for i := int64(0); i < v.len; i++ { - if i > 0 { - res += ", " - } - res += v.elem(i).String() - } - return res + "}" -} - -func (v remoteArray) Assign(t *eval.Thread, o eval.Value) { - // TODO(austin) Could do a bigger memcpy if o is a - // remoteArray in the same Process. - oa := o.(eval.ArrayValue) - for i := int64(0); i < v.len; i++ { - v.Elem(t, i).Assign(t, oa.Elem(t, i)) - } -} - -func (v remoteArray) Get(t *eval.Thread) eval.ArrayValue { - return v -} - -func (v remoteArray) Elem(t *eval.Thread, i int64) eval.Value { - return v.elem(i) -} - -func (v remoteArray) elem(i int64) eval.Value { - return v.elemType.mk(v.r.plus(proc.Word(int64(v.elemType.size) * i))) -} - -func (v remoteArray) Sub(i int64, len int64) eval.ArrayValue { - return remoteArray{v.r.plus(proc.Word(int64(v.elemType.size) * i)), len, v.elemType} -} - -/* - * Struct - */ - -type remoteStruct struct { - r remote - layout []remoteStructField -} - -type remoteStructField struct { - offset int - fieldType *remoteType -} - -func (v remoteStruct) String() string { - res := "{" - for i := range v.layout { - if i > 0 { - res += ", " - } - res += v.field(i).String() - } - return res + "}" -} - -func (v remoteStruct) Assign(t *eval.Thread, o eval.Value) { - // TODO(austin) Could do a bigger memcpy. - oa := o.(eval.StructValue) - l := len(v.layout) - for i := 0; i < l; i++ { - v.Field(t, i).Assign(t, oa.Field(t, i)) - } -} - -func (v remoteStruct) Get(t *eval.Thread) eval.StructValue { - return v -} - -func (v remoteStruct) Field(t *eval.Thread, i int) eval.Value { - return v.field(i) -} - -func (v remoteStruct) field(i int) eval.Value { - f := &v.layout[i] - return f.fieldType.mk(v.r.plus(proc.Word(f.offset))) -} - -func (v remoteStruct) addr() remote { return v.r } - -/* - * Pointer - */ - -// TODO(austin) Comparing two remote pointers for equality in the -// interpreter will crash it because the Value's returned from -// remotePtr.Get() will be structs. - -type remotePtr struct { - r remote - elemType *remoteType -} - -func (v remotePtr) String() string { - return tryRVString(func(a aborter) string { - e := v.aGet(a) - if e == nil { - return "<nil>" - } - return "&" + e.String() - }) -} - -func (v remotePtr) Assign(t *eval.Thread, o eval.Value) { - v.Set(t, o.(eval.PtrValue).Get(t)) -} - -func (v remotePtr) Get(t *eval.Thread) eval.Value { - return v.aGet(t) -} - -func (v remotePtr) aGet(a aborter) eval.Value { - addr := proc.Word(v.r.Get(a, v.r.p.PtrSize())) - if addr == 0 { - return nil - } - return v.elemType.mk(remote{addr, v.r.p}) -} - -func (v remotePtr) Set(t *eval.Thread, x eval.Value) { - v.aSet(t, x) -} - -func (v remotePtr) aSet(a aborter, x eval.Value) { - if x == nil { - v.r.Set(a, v.r.p.PtrSize(), 0) - return - } - xr, ok := x.(remoteValue) - if !ok || v.r.p != xr.addr().p { - a.Abort(RemoteMismatchError("remote pointer must point within the same process")) - } - v.r.Set(a, v.r.p.PtrSize(), uint64(xr.addr().base)) -} - -func (v remotePtr) addr() remote { return v.r } - -/* - * Slice - */ - -type remoteSlice struct { - r remote - elemType *remoteType -} - -func (v remoteSlice) String() string { - return tryRVString(func(a aborter) string { - b := v.aGet(a).Base - if b == nil { - return "<nil>" - } - return b.String() - }) -} - -func (v remoteSlice) Assign(t *eval.Thread, o eval.Value) { - v.Set(t, o.(eval.SliceValue).Get(t)) -} - -func (v remoteSlice) Get(t *eval.Thread) eval.Slice { - return v.aGet(t) -} - -func (v remoteSlice) aGet(a aborter) eval.Slice { - rs := v.r.p.runtime.Slice.mk(v.r).(remoteStruct) - base := proc.Word(rs.field(v.r.p.f.Slice.Array).(remoteUint).aGet(a)) - nel := rs.field(v.r.p.f.Slice.Len).(remoteInt).aGet(a) - cap := rs.field(v.r.p.f.Slice.Cap).(remoteInt).aGet(a) - if base == 0 { - return eval.Slice{nil, nel, cap} - } - return eval.Slice{remoteArray{remote{base, v.r.p}, nel, v.elemType}, nel, cap} -} - -func (v remoteSlice) Set(t *eval.Thread, x eval.Slice) { - v.aSet(t, x) -} - -func (v remoteSlice) aSet(a aborter, x eval.Slice) { - rs := v.r.p.runtime.Slice.mk(v.r).(remoteStruct) - if x.Base == nil { - rs.field(v.r.p.f.Slice.Array).(remoteUint).aSet(a, 0) - } else { - ar, ok := x.Base.(remoteArray) - if !ok || v.r.p != ar.r.p { - a.Abort(RemoteMismatchError("remote slice must point within the same process")) - } - rs.field(v.r.p.f.Slice.Array).(remoteUint).aSet(a, uint64(ar.r.base)) - } - rs.field(v.r.p.f.Slice.Len).(remoteInt).aSet(a, x.Len) - rs.field(v.r.p.f.Slice.Cap).(remoteInt).aSet(a, x.Cap) -} diff --git a/libgo/go/exp/ogle/vars.go b/libgo/go/exp/ogle/vars.go deleted file mode 100644 index 8a3a14791db..00000000000 --- a/libgo/go/exp/ogle/vars.go +++ /dev/null @@ -1,272 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ogle - -import ( - "debug/gosym" - "debug/proc" - "exp/eval" - "log" - "os" -) - -/* - * Remote frame pointers - */ - -// A NotOnStack error occurs when attempting to access a variable in a -// remote frame where that remote frame is not on the current stack. -type NotOnStack struct { - Fn *gosym.Func - Goroutine *Goroutine -} - -func (e NotOnStack) String() string { - return "function " + e.Fn.Name + " not on " + e.Goroutine.String() + "'s stack" -} - -// A remoteFramePtr is an implementation of eval.PtrValue that -// represents a pointer to a function frame in a remote process. When -// accessed, this locates the function on the current goroutine's -// stack and returns a structure containing the local variables of -// that function. -type remoteFramePtr struct { - p *Process - fn *gosym.Func - rt *remoteType -} - -func (v remoteFramePtr) String() string { - // TODO(austin): This could be a really awesome string method - return "<remote frame>" -} - -func (v remoteFramePtr) Assign(t *eval.Thread, o eval.Value) { - v.Set(t, o.(eval.PtrValue).Get(t)) -} - -func (v remoteFramePtr) Get(t *eval.Thread) eval.Value { - g := v.p.curGoroutine - if g == nil || g.frame == nil { - t.Abort(NoCurrentGoroutine{}) - } - - for f := g.frame; f != nil; f = f.aOuter(t) { - if f.fn != v.fn { - continue - } - - // TODO(austin): Register for shootdown with f - return v.rt.mk(remote{f.fp, v.p}) - } - - t.Abort(NotOnStack{v.fn, g}) - panic("fail") -} - -func (v remoteFramePtr) Set(t *eval.Thread, x eval.Value) { - // Theoretically this could be a static error. If remote - // packages were packages, remote frames could just be defined - // as constants. - t.Abort(ReadOnlyError("remote frames cannot be assigned to")) -} - -/* - * Remote packages - */ - -// TODO(austin): Remote packages are implemented as structs right now, -// which has some weird consequences. You can attempt to assign to a -// remote package. It also produces terrible error messages. -// Ideally, these would actually be packages, but somehow first-class -// so they could be assigned to other names. - -// A remotePackage is an implementation of eval.StructValue that -// represents a package in a remote process. It's essentially a -// regular struct, except it cannot be assigned to. -type remotePackage struct { - defs []eval.Value -} - -func (v remotePackage) String() string { return "<remote package>" } - -func (v remotePackage) Assign(t *eval.Thread, o eval.Value) { - t.Abort(ReadOnlyError("remote packages cannot be assigned to")) -} - -func (v remotePackage) Get(t *eval.Thread) eval.StructValue { - return v -} - -func (v remotePackage) Field(t *eval.Thread, i int) eval.Value { - return v.defs[i] -} - -/* - * Remote variables - */ - -// populateWorld defines constants in the given world for each package -// in this process. These packages are structs that, in turn, contain -// fields for each global and function in that package. -func (p *Process) populateWorld(w *eval.World) os.Error { - type def struct { - t eval.Type - v eval.Value - } - packages := make(map[string]map[string]def) - - for _, s := range p.syms.Syms { - if s.ReceiverName() != "" { - // TODO(austin) - continue - } - - // Package - pkgName := s.PackageName() - switch pkgName { - case "", "type", "extratype", "string", "go": - // "go" is really "go.string" - continue - } - pkg, ok := packages[pkgName] - if !ok { - pkg = make(map[string]def) - packages[pkgName] = pkg - } - - // Symbol name - name := s.BaseName() - if _, ok := pkg[name]; ok { - log.Printf("Multiple definitions of symbol %s", s.Name) - continue - } - - // Symbol type - rt, err := p.typeOfSym(&s) - if err != nil { - return err - } - - // Definition - switch s.Type { - case 'D', 'd', 'B', 'b': - // Global variable - if rt == nil { - continue - } - pkg[name] = def{rt.Type, rt.mk(remote{proc.Word(s.Value), p})} - - case 'T', 't', 'L', 'l': - // Function - s := s.Func - // TODO(austin): Ideally, this would *also* be - // callable. How does that interact with type - // conversion syntax? - rt, err := p.makeFrameType(s) - if err != nil { - return err - } - pkg[name] = def{eval.NewPtrType(rt.Type), remoteFramePtr{p, s, rt}} - } - } - - // TODO(austin): Define remote types - - // Define packages - for pkgName, defs := range packages { - fields := make([]eval.StructField, len(defs)) - vals := make([]eval.Value, len(defs)) - i := 0 - for name, def := range defs { - fields[i].Name = name - fields[i].Type = def.t - vals[i] = def.v - i++ - } - pkgType := eval.NewStructType(fields) - pkgVal := remotePackage{vals} - - err := w.DefineConst(pkgName, pkgType, pkgVal) - if err != nil { - log.Printf("while defining package %s: %v", pkgName, err) - } - } - - return nil -} - -// typeOfSym returns the type associated with a symbol. If the symbol -// has no type, returns nil. -func (p *Process) typeOfSym(s *gosym.Sym) (*remoteType, os.Error) { - if s.GoType == 0 { - return nil, nil - } - addr := proc.Word(s.GoType) - var rt *remoteType - err := try(func(a aborter) { rt = parseRemoteType(a, p.runtime.Type.mk(remote{addr, p}).(remoteStruct)) }) - if err != nil { - return nil, err - } - return rt, nil -} - -// makeFrameType constructs a struct type for the frame of a function. -// The offsets in this struct type are such that the struct can be -// instantiated at this function's frame pointer. -func (p *Process) makeFrameType(s *gosym.Func) (*remoteType, os.Error) { - n := len(s.Params) + len(s.Locals) - fields := make([]eval.StructField, n) - layout := make([]remoteStructField, n) - i := 0 - - // TODO(austin): There can be multiple locals/parameters with - // the same name. We probably need liveness information to do - // anything about this. Once we have that, perhaps we give - // such fields interface{} type? Or perhaps we disambiguate - // the names with numbers. Disambiguation is annoying for - // things like "i", where there's an obvious right answer. - - for _, param := range s.Params { - rt, err := p.typeOfSym(param) - if err != nil { - return nil, err - } - if rt == nil { - //fmt.Printf(" (no type)\n"); - continue - } - // TODO(austin): Why do local variables carry their - // package name? - fields[i].Name = param.BaseName() - fields[i].Type = rt.Type - // Parameters have positive offsets from FP - layout[i].offset = int(param.Value) - layout[i].fieldType = rt - i++ - } - - for _, local := range s.Locals { - rt, err := p.typeOfSym(local) - if err != nil { - return nil, err - } - if rt == nil { - continue - } - fields[i].Name = local.BaseName() - fields[i].Type = rt.Type - // Locals have negative offsets from FP - PtrSize - layout[i].offset = -int(local.Value) - p.PtrSize() - layout[i].fieldType = rt - i++ - } - - fields = fields[0:i] - layout = layout[0:i] - t := eval.NewStructType(fields) - mk := func(r remote) eval.Value { return remoteStruct{r, layout} } - return &remoteType{t, 0, 0, mk}, nil -} diff --git a/libgo/go/exp/regexp/all_test.go b/libgo/go/exp/regexp/all_test.go new file mode 100644 index 00000000000..77f32ca1a57 --- /dev/null +++ b/libgo/go/exp/regexp/all_test.go @@ -0,0 +1,429 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package regexp + +import ( + "os" + "strings" + "testing" +) + +var good_re = []string{ + ``, + `.`, + `^.$`, + `a`, + `a*`, + `a+`, + `a?`, + `a|b`, + `a*|b*`, + `(a*|b)(c*|d)`, + `[a-z]`, + `[a-abc-c\-\]\[]`, + `[a-z]+`, + `[abc]`, + `[^1234]`, + `[^\n]`, + `\!\\`, +} + +/* +type stringError struct { + re string + err os.Error +} + +var bad_re = []stringError{ + {`*`, ErrBareClosure}, + {`+`, ErrBareClosure}, + {`?`, ErrBareClosure}, + {`(abc`, ErrUnmatchedLpar}, + {`abc)`, ErrUnmatchedRpar}, + {`x[a-z`, ErrUnmatchedLbkt}, + {`abc]`, ErrUnmatchedRbkt}, + {`[z-a]`, ErrBadRange}, + {`abc\`, ErrExtraneousBackslash}, + {`a**`, ErrBadClosure}, + {`a*+`, ErrBadClosure}, + {`a??`, ErrBadClosure}, + {`\x`, ErrBadBackslash}, +} +*/ + +func compileTest(t *testing.T, expr string, error os.Error) *Regexp { + re, err := Compile(expr) + if err != error { + t.Error("compiling `", expr, "`; unexpected error: ", err.String()) + } + return re +} + +func TestGoodCompile(t *testing.T) { + for i := 0; i < len(good_re); i++ { + compileTest(t, good_re[i], nil) + } +} + +/* +func TestBadCompile(t *testing.T) { + for i := 0; i < len(bad_re); i++ { + compileTest(t, bad_re[i].re, bad_re[i].err) + } +} +*/ + +func matchTest(t *testing.T, test *FindTest) { + re := compileTest(t, test.pat, nil) + if re == nil { + return + } + m := re.MatchString(test.text) + if m != (len(test.matches) > 0) { + t.Errorf("MatchString failure on %s: %t should be %t", test, m, len(test.matches) > 0) + } + // now try bytes + m = re.Match([]byte(test.text)) + if m != (len(test.matches) > 0) { + t.Errorf("Match failure on %s: %t should be %t", test, m, len(test.matches) > 0) + } +} + +func TestMatch(t *testing.T) { + for _, test := range findTests { + matchTest(t, &test) + } +} + +func matchFunctionTest(t *testing.T, test *FindTest) { + m, err := MatchString(test.pat, test.text) + if err == nil { + return + } + if m != (len(test.matches) > 0) { + t.Errorf("Match failure on %s: %t should be %t", test, m, len(test.matches) > 0) + } +} + +func TestMatchFunction(t *testing.T) { + for _, test := range findTests { + matchFunctionTest(t, &test) + } +} + +type ReplaceTest struct { + pattern, replacement, input, output string +} + +var replaceTests = []ReplaceTest{ + // Test empty input and/or replacement, with pattern that matches the empty string. + {"", "", "", ""}, + {"", "x", "", "x"}, + {"", "", "abc", "abc"}, + {"", "x", "abc", "xaxbxcx"}, + + // Test empty input and/or replacement, with pattern that does not match the empty string. + {"b", "", "", ""}, + {"b", "x", "", ""}, + {"b", "", "abc", "ac"}, + {"b", "x", "abc", "axc"}, + {"y", "", "", ""}, + {"y", "x", "", ""}, + {"y", "", "abc", "abc"}, + {"y", "x", "abc", "abc"}, + + // Multibyte characters -- verify that we don't try to match in the middle + // of a character. + {"[a-c]*", "x", "\u65e5", "x\u65e5x"}, + {"[^\u65e5]", "x", "abc\u65e5def", "xxx\u65e5xxx"}, + + // Start and end of a string. + {"^[a-c]*", "x", "abcdabc", "xdabc"}, + {"[a-c]*$", "x", "abcdabc", "abcdx"}, + {"^[a-c]*$", "x", "abcdabc", "abcdabc"}, + {"^[a-c]*", "x", "abc", "x"}, + {"[a-c]*$", "x", "abc", "x"}, + {"^[a-c]*$", "x", "abc", "x"}, + {"^[a-c]*", "x", "dabce", "xdabce"}, + {"[a-c]*$", "x", "dabce", "dabcex"}, + {"^[a-c]*$", "x", "dabce", "dabce"}, + {"^[a-c]*", "x", "", "x"}, + {"[a-c]*$", "x", "", "x"}, + {"^[a-c]*$", "x", "", "x"}, + + {"^[a-c]+", "x", "abcdabc", "xdabc"}, + {"[a-c]+$", "x", "abcdabc", "abcdx"}, + {"^[a-c]+$", "x", "abcdabc", "abcdabc"}, + {"^[a-c]+", "x", "abc", "x"}, + {"[a-c]+$", "x", "abc", "x"}, + {"^[a-c]+$", "x", "abc", "x"}, + {"^[a-c]+", "x", "dabce", "dabce"}, + {"[a-c]+$", "x", "dabce", "dabce"}, + {"^[a-c]+$", "x", "dabce", "dabce"}, + {"^[a-c]+", "x", "", ""}, + {"[a-c]+$", "x", "", ""}, + {"^[a-c]+$", "x", "", ""}, + + // Other cases. + {"abc", "def", "abcdefg", "defdefg"}, + {"bc", "BC", "abcbcdcdedef", "aBCBCdcdedef"}, + {"abc", "", "abcdabc", "d"}, + {"x", "xXx", "xxxXxxx", "xXxxXxxXxXxXxxXxxXx"}, + {"abc", "d", "", ""}, + {"abc", "d", "abc", "d"}, + {".+", "x", "abc", "x"}, + {"[a-c]*", "x", "def", "xdxexfx"}, + {"[a-c]+", "x", "abcbcdcdedef", "xdxdedef"}, + {"[a-c]*", "x", "abcbcdcdedef", "xdxdxexdxexfx"}, +} + +type ReplaceFuncTest struct { + pattern string + replacement func(string) string + input, output string +} + +var replaceFuncTests = []ReplaceFuncTest{ + {"[a-c]", func(s string) string { return "x" + s + "y" }, "defabcdef", "defxayxbyxcydef"}, + {"[a-c]+", func(s string) string { return "x" + s + "y" }, "defabcdef", "defxabcydef"}, + {"[a-c]*", func(s string) string { return "x" + s + "y" }, "defabcdef", "xydxyexyfxabcydxyexyfxy"}, +} + +func TestReplaceAll(t *testing.T) { + for _, tc := range replaceTests { + re, err := Compile(tc.pattern) + if err != nil { + t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err) + continue + } + actual := re.ReplaceAllString(tc.input, tc.replacement) + if actual != tc.output { + t.Errorf("%q.Replace(%q,%q) = %q; want %q", + tc.pattern, tc.input, tc.replacement, actual, tc.output) + } + // now try bytes + actual = string(re.ReplaceAll([]byte(tc.input), []byte(tc.replacement))) + if actual != tc.output { + t.Errorf("%q.Replace(%q,%q) = %q; want %q", + tc.pattern, tc.input, tc.replacement, actual, tc.output) + } + } +} + +func TestReplaceAllFunc(t *testing.T) { + for _, tc := range replaceFuncTests { + re, err := Compile(tc.pattern) + if err != nil { + t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err) + continue + } + actual := re.ReplaceAllStringFunc(tc.input, tc.replacement) + if actual != tc.output { + t.Errorf("%q.ReplaceFunc(%q,%q) = %q; want %q", + tc.pattern, tc.input, tc.replacement, actual, tc.output) + } + // now try bytes + actual = string(re.ReplaceAllFunc([]byte(tc.input), func(s []byte) []byte { return []byte(tc.replacement(string(s))) })) + if actual != tc.output { + t.Errorf("%q.ReplaceFunc(%q,%q) = %q; want %q", + tc.pattern, tc.input, tc.replacement, actual, tc.output) + } + } +} + +type MetaTest struct { + pattern, output, literal string + isLiteral bool +} + +var metaTests = []MetaTest{ + {``, ``, ``, true}, + {`foo`, `foo`, `foo`, true}, + {`foo\.\$`, `foo\\\.\\\$`, `foo.$`, true}, // has meta but no operator + {`foo.\$`, `foo\.\\\$`, `foo`, false}, // has escaped operators and real operators + {`!@#$%^&*()_+-=[{]}\|,<.>/?~`, `!@#\$%\^&\*\(\)_\+-=\[\{\]\}\\\|,<\.>/\?~`, `!@#`, false}, +} + +func TestQuoteMeta(t *testing.T) { + for _, tc := range metaTests { + // Verify that QuoteMeta returns the expected string. + quoted := QuoteMeta(tc.pattern) + if quoted != tc.output { + t.Errorf("QuoteMeta(`%s`) = `%s`; want `%s`", + tc.pattern, quoted, tc.output) + continue + } + + // Verify that the quoted string is in fact treated as expected + // by Compile -- i.e. that it matches the original, unquoted string. + if tc.pattern != "" { + re, err := Compile(quoted) + if err != nil { + t.Errorf("Unexpected error compiling QuoteMeta(`%s`): %v", tc.pattern, err) + continue + } + src := "abc" + tc.pattern + "def" + repl := "xyz" + replaced := re.ReplaceAllString(src, repl) + expected := "abcxyzdef" + if replaced != expected { + t.Errorf("QuoteMeta(`%s`).Replace(`%s`,`%s`) = `%s`; want `%s`", + tc.pattern, src, repl, replaced, expected) + } + } + } +} + +func TestLiteralPrefix(t *testing.T) { + for _, tc := range metaTests { + // Literal method needs to scan the pattern. + re := MustCompile(tc.pattern) + str, complete := re.LiteralPrefix() + if complete != tc.isLiteral { + t.Errorf("LiteralPrefix(`%s`) = %t; want %t", tc.pattern, complete, tc.isLiteral) + } + if str != tc.literal { + t.Errorf("LiteralPrefix(`%s`) = `%s`; want `%s`", tc.pattern, str, tc.literal) + } + } +} + +type numSubexpCase struct { + input string + expected int +} + +var numSubexpCases = []numSubexpCase{ + {``, 0}, + {`.*`, 0}, + {`abba`, 0}, + {`ab(b)a`, 1}, + {`ab(.*)a`, 1}, + {`(.*)ab(.*)a`, 2}, + {`(.*)(ab)(.*)a`, 3}, + {`(.*)((a)b)(.*)a`, 4}, + {`(.*)(\(ab)(.*)a`, 3}, + {`(.*)(\(a\)b)(.*)a`, 3}, +} + +func TestNumSubexp(t *testing.T) { + for _, c := range numSubexpCases { + re := MustCompile(c.input) + n := re.NumSubexp() + if n != c.expected { + t.Errorf("NumSubexp for %q returned %d, expected %d", c.input, n, c.expected) + } + } +} + +func BenchmarkLiteral(b *testing.B) { + x := strings.Repeat("x", 50) + "y" + b.StopTimer() + re := MustCompile("y") + b.StartTimer() + for i := 0; i < b.N; i++ { + if !re.MatchString(x) { + println("no match!") + break + } + } +} + +func BenchmarkNotLiteral(b *testing.B) { + x := strings.Repeat("x", 50) + "y" + b.StopTimer() + re := MustCompile(".y") + b.StartTimer() + for i := 0; i < b.N; i++ { + if !re.MatchString(x) { + println("no match!") + break + } + } +} + +func BenchmarkMatchClass(b *testing.B) { + b.StopTimer() + x := strings.Repeat("xxxx", 20) + "w" + re := MustCompile("[abcdw]") + b.StartTimer() + for i := 0; i < b.N; i++ { + if !re.MatchString(x) { + println("no match!") + break + } + } +} + +func BenchmarkMatchClass_InRange(b *testing.B) { + b.StopTimer() + // 'b' is between 'a' and 'c', so the charclass + // range checking is no help here. + x := strings.Repeat("bbbb", 20) + "c" + re := MustCompile("[ac]") + b.StartTimer() + for i := 0; i < b.N; i++ { + if !re.MatchString(x) { + println("no match!") + break + } + } +} + +func BenchmarkReplaceAll(b *testing.B) { + x := "abcdefghijklmnopqrstuvwxyz" + b.StopTimer() + re := MustCompile("[cjrw]") + b.StartTimer() + for i := 0; i < b.N; i++ { + re.ReplaceAllString(x, "") + } +} + +func BenchmarkAnchoredLiteralShortNonMatch(b *testing.B) { + b.StopTimer() + x := []byte("abcdefghijklmnopqrstuvwxyz") + re := MustCompile("^zbc(d|e)") + b.StartTimer() + for i := 0; i < b.N; i++ { + re.Match(x) + } +} + +func BenchmarkAnchoredLiteralLongNonMatch(b *testing.B) { + b.StopTimer() + x := []byte("abcdefghijklmnopqrstuvwxyz") + for i := 0; i < 15; i++ { + x = append(x, x...) + } + re := MustCompile("^zbc(d|e)") + b.StartTimer() + for i := 0; i < b.N; i++ { + re.Match(x) + } +} + +func BenchmarkAnchoredShortMatch(b *testing.B) { + b.StopTimer() + x := []byte("abcdefghijklmnopqrstuvwxyz") + re := MustCompile("^.bc(d|e)") + b.StartTimer() + for i := 0; i < b.N; i++ { + re.Match(x) + } +} + +func BenchmarkAnchoredLongMatch(b *testing.B) { + b.StopTimer() + x := []byte("abcdefghijklmnopqrstuvwxyz") + for i := 0; i < 15; i++ { + x = append(x, x...) + } + re := MustCompile("^.bc(d|e)") + b.StartTimer() + for i := 0; i < b.N; i++ { + re.Match(x) + } +} diff --git a/libgo/go/exp/regexp/exec.go b/libgo/go/exp/regexp/exec.go new file mode 100644 index 00000000000..0670bb9b1b4 --- /dev/null +++ b/libgo/go/exp/regexp/exec.go @@ -0,0 +1,295 @@ +package regexp + +import "exp/regexp/syntax" + +// A queue is a 'sparse array' holding pending threads of execution. +// See http://research.swtch.com/2008/03/using-uninitialized-memory-for-fun-and.html +type queue struct { + sparse []uint32 + dense []entry +} + +// A entry is an entry on a queue. +// It holds both the instruction pc and the actual thread. +// Some queue entries are just place holders so that the machine +// knows it has considered that pc. Such entries have t == nil. +type entry struct { + pc uint32 + t *thread +} + +// A thread is the state of a single path through the machine: +// an instruction and a corresponding capture array. +// See http://swtch.com/~rsc/regexp/regexp2.html +type thread struct { + inst *syntax.Inst + cap []int +} + +// A machine holds all the state during an NFA simulation for p. +type machine struct { + re *Regexp // corresponding Regexp + p *syntax.Prog // compiled program + q0, q1 queue // two queues for runq, nextq + pool []*thread // pool of available threads + matched bool // whether a match was found + matchcap []int // capture information for the match +} + +// progMachine returns a new machine running the prog p. +func progMachine(p *syntax.Prog) *machine { + m := &machine{p: p} + n := len(m.p.Inst) + m.q0 = queue{make([]uint32, n), make([]entry, 0, n)} + m.q1 = queue{make([]uint32, n), make([]entry, 0, n)} + ncap := p.NumCap + if ncap < 2 { + ncap = 2 + } + m.matchcap = make([]int, ncap) + return m +} + +// alloc allocates a new thread with the given instruction. +// It uses the free pool if possible. +func (m *machine) alloc(i *syntax.Inst) *thread { + var t *thread + if n := len(m.pool); n > 0 { + t = m.pool[n-1] + m.pool = m.pool[:n-1] + } else { + t = new(thread) + t.cap = make([]int, cap(m.matchcap)) + } + t.cap = t.cap[:len(m.matchcap)] + t.inst = i + return t +} + +// free returns t to the free pool. +func (m *machine) free(t *thread) { + m.pool = append(m.pool, t) +} + +// match runs the machine over the input starting at pos. +// It reports whether a match was found. +// If so, m.matchcap holds the submatch information. +func (m *machine) match(i input, pos int) bool { + startCond := m.re.cond + if startCond == ^syntax.EmptyOp(0) { // impossible + return false + } + m.matched = false + for i := range m.matchcap { + m.matchcap[i] = -1 + } + runq, nextq := &m.q0, &m.q1 + rune, rune1 := endOfText, endOfText + width, width1 := 0, 0 + rune, width = i.step(pos) + if rune != endOfText { + rune1, width1 = i.step(pos + width) + } + // TODO: Let caller specify the initial flag setting. + // For now assume pos == 0 is beginning of text and + // pos != 0 is not even beginning of line. + // TODO: Word boundary. + var flag syntax.EmptyOp + if pos == 0 { + flag = syntax.EmptyBeginText | syntax.EmptyBeginLine + } + + // Update flag using lookahead rune. + if rune1 == '\n' { + flag |= syntax.EmptyEndLine + } + if rune1 == endOfText { + flag |= syntax.EmptyEndText + } + + for { + if len(runq.dense) == 0 { + if startCond&syntax.EmptyBeginText != 0 && pos != 0 { + // Anchored match, past beginning of text. + break + } + if m.matched { + // Have match; finished exploring alternatives. + break + } + if len(m.re.prefix) > 0 && rune1 != m.re.prefixRune && i.canCheckPrefix() { + // Match requires literal prefix; fast search for it. + advance := i.index(m.re, pos) + if advance < 0 { + break + } + pos += advance + rune, width = i.step(pos) + rune1, width1 = i.step(pos + width) + } + } + if !m.matched { + if len(m.matchcap) > 0 { + m.matchcap[0] = pos + } + m.add(runq, uint32(m.p.Start), pos, m.matchcap, flag) + } + // TODO: word boundary + flag = 0 + if rune == '\n' { + flag |= syntax.EmptyBeginLine + } + if rune1 == '\n' { + flag |= syntax.EmptyEndLine + } + if rune1 == endOfText { + flag |= syntax.EmptyEndText + } + m.step(runq, nextq, pos, pos+width, rune, flag) + if width == 0 { + break + } + pos += width + rune, width = rune1, width1 + if rune != endOfText { + rune1, width1 = i.step(pos + width) + } + runq, nextq = nextq, runq + } + m.clear(nextq) + return m.matched +} + +// clear frees all threads on the thread queue. +func (m *machine) clear(q *queue) { + for _, d := range q.dense { + if d.t != nil { + m.free(d.t) + } + } + q.dense = q.dense[:0] +} + +// step executes one step of the machine, running each of the threads +// on runq and appending new threads to nextq. +// The step processes the rune c (which may be endOfText), +// which starts at position pos and ends at nextPos. +// nextCond gives the setting for the empty-width flags after c. +func (m *machine) step(runq, nextq *queue, pos, nextPos, c int, nextCond syntax.EmptyOp) { + for j := 0; j < len(runq.dense); j++ { + d := &runq.dense[j] + t := d.t + if t == nil { + continue + } + /* + * If we support leftmost-longest matching: + if longest && matched && match[0] < t.cap[0] { + m.free(t) + continue + } + */ + + i := t.inst + switch i.Op { + default: + panic("bad inst") + + case syntax.InstMatch: + if len(t.cap) > 0 { + t.cap[1] = pos + copy(m.matchcap, t.cap) + } + m.matched = true + for _, d := range runq.dense[j+1:] { + if d.t != nil { + m.free(d.t) + } + } + runq.dense = runq.dense[:0] + + case syntax.InstRune: + if i.MatchRune(c) { + m.add(nextq, i.Out, nextPos, t.cap, nextCond) + } + } + m.free(t) + } + runq.dense = runq.dense[:0] +} + +// add adds an entry to q for pc, unless the q already has such an entry. +// It also recursively adds an entry for all instructions reachable from pc by following +// empty-width conditions satisfied by cond. pos gives the current position +// in the input. +func (m *machine) add(q *queue, pc uint32, pos int, cap []int, cond syntax.EmptyOp) { + if pc == 0 { + return + } + if j := q.sparse[pc]; j < uint32(len(q.dense)) && q.dense[j].pc == pc { + return + } + + j := len(q.dense) + q.dense = q.dense[:j+1] + d := &q.dense[j] + d.t = nil + d.pc = pc + q.sparse[pc] = uint32(j) + + i := &m.p.Inst[pc] + switch i.Op { + default: + panic("unhandled") + case syntax.InstFail: + // nothing + case syntax.InstAlt, syntax.InstAltMatch: + m.add(q, i.Out, pos, cap, cond) + m.add(q, i.Arg, pos, cap, cond) + case syntax.InstEmptyWidth: + if syntax.EmptyOp(i.Arg)&^cond == 0 { + m.add(q, i.Out, pos, cap, cond) + } + case syntax.InstNop: + m.add(q, i.Out, pos, cap, cond) + case syntax.InstCapture: + if int(i.Arg) < len(cap) { + opos := cap[i.Arg] + cap[i.Arg] = pos + m.add(q, i.Out, pos, cap, cond) + cap[i.Arg] = opos + } else { + m.add(q, i.Out, pos, cap, cond) + } + case syntax.InstMatch, syntax.InstRune: + t := m.alloc(i) + if len(t.cap) > 0 { + copy(t.cap, cap) + } + d.t = t + } +} + +// empty is a non-nil 0-element slice, +// so doExecute can avoid an allocation +// when 0 captures are requested from a successful match. +var empty = make([]int, 0) + +// doExecute finds the leftmost match in the input and returns +// the position of its subexpressions. +func (re *Regexp) doExecute(i input, pos int, ncap int) []int { + m := re.get() + m.matchcap = m.matchcap[:ncap] + if !m.match(i, pos) { + re.put(m) + return nil + } + if ncap == 0 { + re.put(m) + return empty // empty but not nil + } + cap := make([]int, ncap) + copy(cap, m.matchcap) + re.put(m) + return cap +} diff --git a/libgo/go/exp/regexp/find_test.go b/libgo/go/exp/regexp/find_test.go new file mode 100644 index 00000000000..dddc3484c93 --- /dev/null +++ b/libgo/go/exp/regexp/find_test.go @@ -0,0 +1,472 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package regexp + +import ( + "fmt" + "strings" + "testing" +) + +// For each pattern/text pair, what is the expected output of each function? +// We can derive the textual results from the indexed results, the non-submatch +// results from the submatched results, the single results from the 'all' results, +// and the byte results from the string results. Therefore the table includes +// only the FindAllStringSubmatchIndex result. +type FindTest struct { + pat string + text string + matches [][]int +} + +func (t FindTest) String() string { + return fmt.Sprintf("pat: %#q text: %#q", t.pat, t.text) +} + +var findTests = []FindTest{ + {``, ``, build(1, 0, 0)}, + {`^abcdefg`, "abcdefg", build(1, 0, 7)}, + {`a+`, "baaab", build(1, 1, 4)}, + {"abcd..", "abcdef", build(1, 0, 6)}, + {`a`, "a", build(1, 0, 1)}, + {`x`, "y", nil}, + {`b`, "abc", build(1, 1, 2)}, + {`.`, "a", build(1, 0, 1)}, + {`.*`, "abcdef", build(1, 0, 6)}, + {`^`, "abcde", build(1, 0, 0)}, + {`$`, "abcde", build(1, 5, 5)}, + {`^abcd$`, "abcd", build(1, 0, 4)}, + {`^bcd'`, "abcdef", nil}, + {`^abcd$`, "abcde", nil}, + {`a+`, "baaab", build(1, 1, 4)}, + {`a*`, "baaab", build(3, 0, 0, 1, 4, 5, 5)}, + {`[a-z]+`, "abcd", build(1, 0, 4)}, + {`[^a-z]+`, "ab1234cd", build(1, 2, 6)}, + {`[a\-\]z]+`, "az]-bcz", build(2, 0, 4, 6, 7)}, + {`[^\n]+`, "abcd\n", build(1, 0, 4)}, + {`[日本語]+`, "日本語日本語", build(1, 0, 18)}, + {`日本語+`, "日本語", build(1, 0, 9)}, + {`日本語+`, "日本語語語語", build(1, 0, 18)}, + {`()`, "", build(1, 0, 0, 0, 0)}, + {`(a)`, "a", build(1, 0, 1, 0, 1)}, + {`(.)(.)`, "日a", build(1, 0, 4, 0, 3, 3, 4)}, + {`(.*)`, "", build(1, 0, 0, 0, 0)}, + {`(.*)`, "abcd", build(1, 0, 4, 0, 4)}, + {`(..)(..)`, "abcd", build(1, 0, 4, 0, 2, 2, 4)}, + {`(([^xyz]*)(d))`, "abcd", build(1, 0, 4, 0, 4, 0, 3, 3, 4)}, + {`((a|b|c)*(d))`, "abcd", build(1, 0, 4, 0, 4, 2, 3, 3, 4)}, + {`(((a|b|c)*)(d))`, "abcd", build(1, 0, 4, 0, 4, 0, 3, 2, 3, 3, 4)}, + {`\a\f\n\r\t\v`, "\a\f\n\r\t\v", build(1, 0, 6)}, + {`[\a\f\n\r\t\v]+`, "\a\f\n\r\t\v", build(1, 0, 6)}, + + {`a*(|(b))c*`, "aacc", build(1, 0, 4, 2, 2, -1, -1)}, + {`(.*).*`, "ab", build(1, 0, 2, 0, 2)}, + {`[.]`, ".", build(1, 0, 1)}, + {`/$`, "/abc/", build(1, 4, 5)}, + {`/$`, "/abc", nil}, + + // multiple matches + {`.`, "abc", build(3, 0, 1, 1, 2, 2, 3)}, + {`(.)`, "abc", build(3, 0, 1, 0, 1, 1, 2, 1, 2, 2, 3, 2, 3)}, + {`.(.)`, "abcd", build(2, 0, 2, 1, 2, 2, 4, 3, 4)}, + {`ab*`, "abbaab", build(3, 0, 3, 3, 4, 4, 6)}, + {`a(b*)`, "abbaab", build(3, 0, 3, 1, 3, 3, 4, 4, 4, 4, 6, 5, 6)}, + + // fixed bugs + {`ab$`, "cab", build(1, 1, 3)}, + {`axxb$`, "axxcb", nil}, + {`data`, "daXY data", build(1, 5, 9)}, + {`da(.)a$`, "daXY data", build(1, 5, 9, 7, 8)}, + {`zx+`, "zzx", build(1, 1, 3)}, + + // can backslash-escape any punctuation + {`\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\{\|\}\~`, + `!"#$%&'()*+,-./:;<=>?@[\]^_{|}~`, build(1, 0, 31)}, + {`[\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\{\|\}\~]+`, + `!"#$%&'()*+,-./:;<=>?@[\]^_{|}~`, build(1, 0, 31)}, + {"\\`", "`", build(1, 0, 1)}, + {"[\\`]+", "`", build(1, 0, 1)}, + + // long set of matches (longer than startSize) + { + ".", + "qwertyuiopasdfghjklzxcvbnm1234567890", + build(36, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, + 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, + 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, + 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36), + }, +} + +// build is a helper to construct a [][]int by extracting n sequences from x. +// This represents n matches with len(x)/n submatches each. +func build(n int, x ...int) [][]int { + ret := make([][]int, n) + runLength := len(x) / n + j := 0 + for i := range ret { + ret[i] = make([]int, runLength) + copy(ret[i], x[j:]) + j += runLength + if j > len(x) { + panic("invalid build entry") + } + } + return ret +} + +// First the simple cases. + +func TestFind(t *testing.T) { + for _, test := range findTests { + re := MustCompile(test.pat) + if re.String() != test.pat { + t.Errorf("String() = `%s`; should be `%s`", re.String(), test.pat) + } + result := re.Find([]byte(test.text)) + switch { + case len(test.matches) == 0 && len(result) == 0: + // ok + case test.matches == nil && result != nil: + t.Errorf("expected no match; got one: %s", test) + case test.matches != nil && result == nil: + t.Errorf("expected match; got none: %s", test) + case test.matches != nil && result != nil: + expect := test.text[test.matches[0][0]:test.matches[0][1]] + if expect != string(result) { + t.Errorf("expected %q got %q: %s", expect, result, test) + } + } + } +} + +func TestFindString(t *testing.T) { + for _, test := range findTests { + result := MustCompile(test.pat).FindString(test.text) + switch { + case len(test.matches) == 0 && len(result) == 0: + // ok + case test.matches == nil && result != "": + t.Errorf("expected no match; got one: %s", test) + case test.matches != nil && result == "": + // Tricky because an empty result has two meanings: no match or empty match. + if test.matches[0][0] != test.matches[0][1] { + t.Errorf("expected match; got none: %s", test) + } + case test.matches != nil && result != "": + expect := test.text[test.matches[0][0]:test.matches[0][1]] + if expect != result { + t.Errorf("expected %q got %q: %s", expect, result, test) + } + } + } +} + +func testFindIndex(test *FindTest, result []int, t *testing.T) { + switch { + case len(test.matches) == 0 && len(result) == 0: + // ok + case test.matches == nil && result != nil: + t.Errorf("expected no match; got one: %s", test) + case test.matches != nil && result == nil: + t.Errorf("expected match; got none: %s", test) + case test.matches != nil && result != nil: + expect := test.matches[0] + if expect[0] != result[0] || expect[1] != result[1] { + t.Errorf("expected %v got %v: %s", expect, result, test) + } + } +} + +func TestFindIndex(t *testing.T) { + for _, test := range findTests { + testFindIndex(&test, MustCompile(test.pat).FindIndex([]byte(test.text)), t) + } +} + +func TestFindStringIndex(t *testing.T) { + for _, test := range findTests { + testFindIndex(&test, MustCompile(test.pat).FindStringIndex(test.text), t) + } +} + +func TestFindReaderIndex(t *testing.T) { + for _, test := range findTests { + testFindIndex(&test, MustCompile(test.pat).FindReaderIndex(strings.NewReader(test.text)), t) + } +} + +// Now come the simple All cases. + +func TestFindAll(t *testing.T) { + for _, test := range findTests { + result := MustCompile(test.pat).FindAll([]byte(test.text), -1) + switch { + case test.matches == nil && result == nil: + // ok + case test.matches == nil && result != nil: + t.Errorf("expected no match; got one: %s", test) + case test.matches != nil && result == nil: + t.Fatalf("expected match; got none: %s", test) + case test.matches != nil && result != nil: + if len(test.matches) != len(result) { + t.Errorf("expected %d matches; got %d: %s", len(test.matches), len(result), test) + continue + } + for k, e := range test.matches { + expect := test.text[e[0]:e[1]] + if expect != string(result[k]) { + t.Errorf("match %d: expected %q got %q: %s", k, expect, result[k], test) + } + } + } + } +} + +func TestFindAllString(t *testing.T) { + for _, test := range findTests { + result := MustCompile(test.pat).FindAllString(test.text, -1) + switch { + case test.matches == nil && result == nil: + // ok + case test.matches == nil && result != nil: + t.Errorf("expected no match; got one: %s", test) + case test.matches != nil && result == nil: + t.Errorf("expected match; got none: %s", test) + case test.matches != nil && result != nil: + if len(test.matches) != len(result) { + t.Errorf("expected %d matches; got %d: %s", len(test.matches), len(result), test) + continue + } + for k, e := range test.matches { + expect := test.text[e[0]:e[1]] + if expect != result[k] { + t.Errorf("expected %q got %q: %s", expect, result, test) + } + } + } + } +} + +func testFindAllIndex(test *FindTest, result [][]int, t *testing.T) { + switch { + case test.matches == nil && result == nil: + // ok + case test.matches == nil && result != nil: + t.Errorf("expected no match; got one: %s", test) + case test.matches != nil && result == nil: + t.Errorf("expected match; got none: %s", test) + case test.matches != nil && result != nil: + if len(test.matches) != len(result) { + t.Errorf("expected %d matches; got %d: %s", len(test.matches), len(result), test) + return + } + for k, e := range test.matches { + if e[0] != result[k][0] || e[1] != result[k][1] { + t.Errorf("match %d: expected %v got %v: %s", k, e, result[k], test) + } + } + } +} + +func TestFindAllIndex(t *testing.T) { + for _, test := range findTests { + testFindAllIndex(&test, MustCompile(test.pat).FindAllIndex([]byte(test.text), -1), t) + } +} + +func TestFindAllStringIndex(t *testing.T) { + for _, test := range findTests { + testFindAllIndex(&test, MustCompile(test.pat).FindAllStringIndex(test.text, -1), t) + } +} + +// Now come the Submatch cases. + +func testSubmatchBytes(test *FindTest, n int, submatches []int, result [][]byte, t *testing.T) { + if len(submatches) != len(result)*2 { + t.Errorf("match %d: expected %d submatches; got %d: %s", n, len(submatches)/2, len(result), test) + return + } + for k := 0; k < len(submatches); k += 2 { + if submatches[k] == -1 { + if result[k/2] != nil { + t.Errorf("match %d: expected nil got %q: %s", n, result, test) + } + continue + } + expect := test.text[submatches[k]:submatches[k+1]] + if expect != string(result[k/2]) { + t.Errorf("match %d: expected %q got %q: %s", n, expect, result, test) + return + } + } +} + +func TestFindSubmatch(t *testing.T) { + for _, test := range findTests { + result := MustCompile(test.pat).FindSubmatch([]byte(test.text)) + switch { + case test.matches == nil && result == nil: + // ok + case test.matches == nil && result != nil: + t.Errorf("expected no match; got one: %s", test) + case test.matches != nil && result == nil: + t.Errorf("expected match; got none: %s", test) + case test.matches != nil && result != nil: + testSubmatchBytes(&test, 0, test.matches[0], result, t) + } + } +} + +func testSubmatchString(test *FindTest, n int, submatches []int, result []string, t *testing.T) { + if len(submatches) != len(result)*2 { + t.Errorf("match %d: expected %d submatches; got %d: %s", n, len(submatches)/2, len(result), test) + return + } + for k := 0; k < len(submatches); k += 2 { + if submatches[k] == -1 { + if result[k/2] != "" { + t.Errorf("match %d: expected nil got %q: %s", n, result, test) + } + continue + } + expect := test.text[submatches[k]:submatches[k+1]] + if expect != result[k/2] { + t.Errorf("match %d: expected %q got %q: %s", n, expect, result, test) + return + } + } +} + +func TestFindStringSubmatch(t *testing.T) { + for _, test := range findTests { + result := MustCompile(test.pat).FindStringSubmatch(test.text) + switch { + case test.matches == nil && result == nil: + // ok + case test.matches == nil && result != nil: + t.Errorf("expected no match; got one: %s", test) + case test.matches != nil && result == nil: + t.Errorf("expected match; got none: %s", test) + case test.matches != nil && result != nil: + testSubmatchString(&test, 0, test.matches[0], result, t) + } + } +} + +func testSubmatchIndices(test *FindTest, n int, expect, result []int, t *testing.T) { + if len(expect) != len(result) { + t.Errorf("match %d: expected %d matches; got %d: %s", n, len(expect)/2, len(result)/2, test) + return + } + for k, e := range expect { + if e != result[k] { + t.Errorf("match %d: submatch error: expected %v got %v: %s", n, expect, result, test) + } + } +} + +func testFindSubmatchIndex(test *FindTest, result []int, t *testing.T) { + switch { + case test.matches == nil && result == nil: + // ok + case test.matches == nil && result != nil: + t.Errorf("expected no match; got one: %s", test) + case test.matches != nil && result == nil: + t.Errorf("expected match; got none: %s", test) + case test.matches != nil && result != nil: + testSubmatchIndices(test, 0, test.matches[0], result, t) + } +} + +func TestFindSubmatchIndex(t *testing.T) { + for _, test := range findTests { + testFindSubmatchIndex(&test, MustCompile(test.pat).FindSubmatchIndex([]byte(test.text)), t) + } +} + +func TestFindStringSubmatchIndex(t *testing.T) { + for _, test := range findTests { + testFindSubmatchIndex(&test, MustCompile(test.pat).FindStringSubmatchIndex(test.text), t) + } +} + +func TestFindReaderSubmatchIndex(t *testing.T) { + for _, test := range findTests { + testFindSubmatchIndex(&test, MustCompile(test.pat).FindReaderSubmatchIndex(strings.NewReader(test.text)), t) + } +} + +// Now come the monster AllSubmatch cases. + +func TestFindAllSubmatch(t *testing.T) { + for _, test := range findTests { + result := MustCompile(test.pat).FindAllSubmatch([]byte(test.text), -1) + switch { + case test.matches == nil && result == nil: + // ok + case test.matches == nil && result != nil: + t.Errorf("expected no match; got one: %s", test) + case test.matches != nil && result == nil: + t.Errorf("expected match; got none: %s", test) + case len(test.matches) != len(result): + t.Errorf("expected %d matches; got %d: %s", len(test.matches), len(result), test) + case test.matches != nil && result != nil: + for k, match := range test.matches { + testSubmatchBytes(&test, k, match, result[k], t) + } + } + } +} + +func TestFindAllStringSubmatch(t *testing.T) { + for _, test := range findTests { + result := MustCompile(test.pat).FindAllStringSubmatch(test.text, -1) + switch { + case test.matches == nil && result == nil: + // ok + case test.matches == nil && result != nil: + t.Errorf("expected no match; got one: %s", test) + case test.matches != nil && result == nil: + t.Errorf("expected match; got none: %s", test) + case len(test.matches) != len(result): + t.Errorf("expected %d matches; got %d: %s", len(test.matches), len(result), test) + case test.matches != nil && result != nil: + for k, match := range test.matches { + testSubmatchString(&test, k, match, result[k], t) + } + } + } +} + +func testFindAllSubmatchIndex(test *FindTest, result [][]int, t *testing.T) { + switch { + case test.matches == nil && result == nil: + // ok + case test.matches == nil && result != nil: + t.Errorf("expected no match; got one: %s", test) + case test.matches != nil && result == nil: + t.Errorf("expected match; got none: %s", test) + case len(test.matches) != len(result): + t.Errorf("expected %d matches; got %d: %s", len(test.matches), len(result), test) + case test.matches != nil && result != nil: + for k, match := range test.matches { + testSubmatchIndices(test, k, match, result[k], t) + } + } +} + +func TestFindAllSubmatchIndex(t *testing.T) { + for _, test := range findTests { + testFindAllSubmatchIndex(&test, MustCompile(test.pat).FindAllSubmatchIndex([]byte(test.text), -1), t) + } +} + +func TestFindAllStringSubmatchIndex(t *testing.T) { + for _, test := range findTests { + testFindAllSubmatchIndex(&test, MustCompile(test.pat).FindAllStringSubmatchIndex(test.text, -1), t) + } +} diff --git a/libgo/go/exp/regexp/regexp.go b/libgo/go/exp/regexp/regexp.go new file mode 100644 index 00000000000..1b75900f816 --- /dev/null +++ b/libgo/go/exp/regexp/regexp.go @@ -0,0 +1,795 @@ +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package regexp implements a simple regular expression library. +// +// The syntax of the regular expressions accepted is the same +// general syntax used by Perl, Python, and other languages. +// More precisely, it is the syntax accepted by RE2 and described at +// http://code.google.com/p/re2/wiki/Syntax, except for \C. +// +// All characters are UTF-8-encoded code points. +// +// There are 16 methods of Regexp that match a regular expression and identify +// the matched text. Their names are matched by this regular expression: +// +// Find(All)?(String)?(Submatch)?(Index)? +// +// If 'All' is present, the routine matches successive non-overlapping +// matches of the entire expression. Empty matches abutting a preceding +// match are ignored. The return value is a slice containing the successive +// return values of the corresponding non-'All' routine. These routines take +// an extra integer argument, n; if n >= 0, the function returns at most n +// matches/submatches. +// +// If 'String' is present, the argument is a string; otherwise it is a slice +// of bytes; return values are adjusted as appropriate. +// +// If 'Submatch' is present, the return value is a slice identifying the +// successive submatches of the expression. Submatches are matches of +// parenthesized subexpressions within the regular expression, numbered from +// left to right in order of opening parenthesis. Submatch 0 is the match of +// the entire expression, submatch 1 the match of the first parenthesized +// subexpression, and so on. +// +// If 'Index' is present, matches and submatches are identified by byte index +// pairs within the input string: result[2*n:2*n+1] identifies the indexes of +// the nth submatch. The pair for n==0 identifies the match of the entire +// expression. If 'Index' is not present, the match is identified by the +// text of the match/submatch. If an index is negative, it means that +// subexpression did not match any string in the input. +// +// There is also a subset of the methods that can be applied to text read +// from a RuneReader: +// +// MatchReader, FindReaderIndex, FindReaderSubmatchIndex +// +// This set may grow. Note that regular expression matches may need to +// examine text beyond the text returned by a match, so the methods that +// match text from a RuneReader may read arbitrarily far into the input +// before returning. +// +// (There are a few other methods that do not match this pattern.) +// +package regexp + +import ( + "bytes" + "exp/regexp/syntax" + "io" + "os" + "strings" + "sync" + "utf8" +) + +var debug = false + +// Error is the local type for a parsing error. +type Error string + +func (e Error) String() string { + return string(e) +} + +// Regexp is the representation of a compiled regular expression. +// The public interface is entirely through methods. +// A Regexp is safe for concurrent use by multiple goroutines. +type Regexp struct { + // read-only after Compile + expr string // as passed to Compile + prog *syntax.Prog // compiled program + prefix string // required prefix in unanchored matches + prefixBytes []byte // prefix, as a []byte + prefixComplete bool // prefix is the entire regexp + prefixRune int // first rune in prefix + cond syntax.EmptyOp // empty-width conditions required at start of match + + // cache of machines for running regexp + mu sync.Mutex + machine []*machine +} + +// String returns the source text used to compile the regular expression. +func (re *Regexp) String() string { + return re.expr +} + +// Compile parses a regular expression and returns, if successful, a Regexp +// object that can be used to match against text. +func Compile(expr string) (*Regexp, os.Error) { + re, err := syntax.Parse(expr, syntax.Perl) + if err != nil { + return nil, err + } + prog, err := syntax.Compile(re) + if err != nil { + return nil, err + } + regexp := &Regexp{ + expr: expr, + prog: prog, + } + regexp.prefix, regexp.prefixComplete = prog.Prefix() + if regexp.prefix != "" { + // TODO(rsc): Remove this allocation by adding + // IndexString to package bytes. + regexp.prefixBytes = []byte(regexp.prefix) + regexp.prefixRune, _ = utf8.DecodeRuneInString(regexp.prefix) + } + regexp.cond = prog.StartCond() + return regexp, nil +} + +// get returns a machine to use for matching re. +// It uses the re's machine cache if possible, to avoid +// unnecessary allocation. +func (re *Regexp) get() *machine { + re.mu.Lock() + if n := len(re.machine); n > 0 { + z := re.machine[n-1] + re.machine = re.machine[:n-1] + re.mu.Unlock() + return z + } + re.mu.Unlock() + z := progMachine(re.prog) + z.re = re + return z +} + +// put returns a machine to the re's machine cache. +// There is no attempt to limit the size of the cache, so it will +// grow to the maximum number of simultaneous matches +// run using re. (The cache empties when re gets garbage collected.) +func (re *Regexp) put(z *machine) { + re.mu.Lock() + re.machine = append(re.machine, z) + re.mu.Unlock() +} + +// MustCompile is like Compile but panics if the expression cannot be parsed. +// It simplifies safe initialization of global variables holding compiled regular +// expressions. +func MustCompile(str string) *Regexp { + regexp, error := Compile(str) + if error != nil { + panic(`regexp: compiling "` + str + `": ` + error.String()) + } + return regexp +} + +// NumSubexp returns the number of parenthesized subexpressions in this Regexp. +func (re *Regexp) NumSubexp() int { + // NumCap/2 because captures count ( and ) separately. + // -1 because NumCap counts $0 but NumSubexp does not. + return re.prog.NumCap/2 - 1 +} + +const endOfText = -1 + +// input abstracts different representations of the input text. It provides +// one-character lookahead. +type input interface { + step(pos int) (rune int, width int) // advance one rune + canCheckPrefix() bool // can we look ahead without losing info? + hasPrefix(re *Regexp) bool + index(re *Regexp, pos int) int +} + +// inputString scans a string. +type inputString struct { + str string +} + +func newInputString(str string) *inputString { + return &inputString{str: str} +} + +func (i *inputString) step(pos int) (int, int) { + if pos < len(i.str) { + return utf8.DecodeRuneInString(i.str[pos:len(i.str)]) + } + return endOfText, 0 +} + +func (i *inputString) canCheckPrefix() bool { + return true +} + +func (i *inputString) hasPrefix(re *Regexp) bool { + return strings.HasPrefix(i.str, re.prefix) +} + +func (i *inputString) index(re *Regexp, pos int) int { + return strings.Index(i.str[pos:], re.prefix) +} + +// inputBytes scans a byte slice. +type inputBytes struct { + str []byte +} + +func newInputBytes(str []byte) *inputBytes { + return &inputBytes{str: str} +} + +func (i *inputBytes) step(pos int) (int, int) { + if pos < len(i.str) { + return utf8.DecodeRune(i.str[pos:len(i.str)]) + } + return endOfText, 0 +} + +func (i *inputBytes) canCheckPrefix() bool { + return true +} + +func (i *inputBytes) hasPrefix(re *Regexp) bool { + return bytes.HasPrefix(i.str, re.prefixBytes) +} + +func (i *inputBytes) index(re *Regexp, pos int) int { + return bytes.Index(i.str[pos:], re.prefixBytes) +} + +// inputReader scans a RuneReader. +type inputReader struct { + r io.RuneReader + atEOT bool + pos int +} + +func newInputReader(r io.RuneReader) *inputReader { + return &inputReader{r: r} +} + +func (i *inputReader) step(pos int) (int, int) { + if !i.atEOT && pos != i.pos { + return endOfText, 0 + + } + r, w, err := i.r.ReadRune() + if err != nil { + i.atEOT = true + return endOfText, 0 + } + i.pos += w + return r, w +} + +func (i *inputReader) canCheckPrefix() bool { + return false +} + +func (i *inputReader) hasPrefix(re *Regexp) bool { + return false +} + +func (i *inputReader) index(re *Regexp, pos int) int { + return -1 +} + +// LiteralPrefix returns a literal string that must begin any match +// of the regular expression re. It returns the boolean true if the +// literal string comprises the entire regular expression. +func (re *Regexp) LiteralPrefix() (prefix string, complete bool) { + return re.prefix, re.prefixComplete +} + +// MatchReader returns whether the Regexp matches the text read by the +// RuneReader. The return value is a boolean: true for match, false for no +// match. +func (re *Regexp) MatchReader(r io.RuneReader) bool { + return re.doExecute(newInputReader(r), 0, 0) != nil +} + +// MatchString returns whether the Regexp matches the string s. +// The return value is a boolean: true for match, false for no match. +func (re *Regexp) MatchString(s string) bool { + return re.doExecute(newInputString(s), 0, 0) != nil +} + +// Match returns whether the Regexp matches the byte slice b. +// The return value is a boolean: true for match, false for no match. +func (re *Regexp) Match(b []byte) bool { + return re.doExecute(newInputBytes(b), 0, 0) != nil +} + +// MatchReader checks whether a textual regular expression matches the text +// read by the RuneReader. More complicated queries need to use Compile and +// the full Regexp interface. +func MatchReader(pattern string, r io.RuneReader) (matched bool, error os.Error) { + re, err := Compile(pattern) + if err != nil { + return false, err + } + return re.MatchReader(r), nil +} + +// MatchString checks whether a textual regular expression +// matches a string. More complicated queries need +// to use Compile and the full Regexp interface. +func MatchString(pattern string, s string) (matched bool, error os.Error) { + re, err := Compile(pattern) + if err != nil { + return false, err + } + return re.MatchString(s), nil +} + +// Match checks whether a textual regular expression +// matches a byte slice. More complicated queries need +// to use Compile and the full Regexp interface. +func Match(pattern string, b []byte) (matched bool, error os.Error) { + re, err := Compile(pattern) + if err != nil { + return false, err + } + return re.Match(b), nil +} + +// ReplaceAllString returns a copy of src in which all matches for the Regexp +// have been replaced by repl. No support is provided for expressions +// (e.g. \1 or $1) in the replacement string. +func (re *Regexp) ReplaceAllString(src, repl string) string { + return re.ReplaceAllStringFunc(src, func(string) string { return repl }) +} + +// ReplaceAllStringFunc returns a copy of src in which all matches for the +// Regexp have been replaced by the return value of of function repl (whose +// first argument is the matched string). No support is provided for +// expressions (e.g. \1 or $1) in the replacement string. +func (re *Regexp) ReplaceAllStringFunc(src string, repl func(string) string) string { + lastMatchEnd := 0 // end position of the most recent match + searchPos := 0 // position where we next look for a match + buf := new(bytes.Buffer) + for searchPos <= len(src) { + a := re.doExecute(newInputString(src), searchPos, 2) + if len(a) == 0 { + break // no more matches + } + + // Copy the unmatched characters before this match. + io.WriteString(buf, src[lastMatchEnd:a[0]]) + + // Now insert a copy of the replacement string, but not for a + // match of the empty string immediately after another match. + // (Otherwise, we get double replacement for patterns that + // match both empty and nonempty strings.) + if a[1] > lastMatchEnd || a[0] == 0 { + io.WriteString(buf, repl(src[a[0]:a[1]])) + } + lastMatchEnd = a[1] + + // Advance past this match; always advance at least one character. + _, width := utf8.DecodeRuneInString(src[searchPos:]) + if searchPos+width > a[1] { + searchPos += width + } else if searchPos+1 > a[1] { + // This clause is only needed at the end of the input + // string. In that case, DecodeRuneInString returns width=0. + searchPos++ + } else { + searchPos = a[1] + } + } + + // Copy the unmatched characters after the last match. + io.WriteString(buf, src[lastMatchEnd:]) + + return buf.String() +} + +// ReplaceAll returns a copy of src in which all matches for the Regexp +// have been replaced by repl. No support is provided for expressions +// (e.g. \1 or $1) in the replacement text. +func (re *Regexp) ReplaceAll(src, repl []byte) []byte { + return re.ReplaceAllFunc(src, func([]byte) []byte { return repl }) +} + +// ReplaceAllFunc returns a copy of src in which all matches for the +// Regexp have been replaced by the return value of of function repl (whose +// first argument is the matched []byte). No support is provided for +// expressions (e.g. \1 or $1) in the replacement string. +func (re *Regexp) ReplaceAllFunc(src []byte, repl func([]byte) []byte) []byte { + lastMatchEnd := 0 // end position of the most recent match + searchPos := 0 // position where we next look for a match + buf := new(bytes.Buffer) + for searchPos <= len(src) { + a := re.doExecute(newInputBytes(src), searchPos, 2) + if len(a) == 0 { + break // no more matches + } + + // Copy the unmatched characters before this match. + buf.Write(src[lastMatchEnd:a[0]]) + + // Now insert a copy of the replacement string, but not for a + // match of the empty string immediately after another match. + // (Otherwise, we get double replacement for patterns that + // match both empty and nonempty strings.) + if a[1] > lastMatchEnd || a[0] == 0 { + buf.Write(repl(src[a[0]:a[1]])) + } + lastMatchEnd = a[1] + + // Advance past this match; always advance at least one character. + _, width := utf8.DecodeRune(src[searchPos:]) + if searchPos+width > a[1] { + searchPos += width + } else if searchPos+1 > a[1] { + // This clause is only needed at the end of the input + // string. In that case, DecodeRuneInString returns width=0. + searchPos++ + } else { + searchPos = a[1] + } + } + + // Copy the unmatched characters after the last match. + buf.Write(src[lastMatchEnd:]) + + return buf.Bytes() +} + +var specialBytes = []byte(`\.+*?()|[]{}^$`) + +func special(b byte) bool { + return bytes.IndexByte(specialBytes, b) >= 0 +} + +// QuoteMeta returns a string that quotes all regular expression metacharacters +// inside the argument text; the returned string is a regular expression matching +// the literal text. For example, QuoteMeta(`[foo]`) returns `\[foo\]`. +func QuoteMeta(s string) string { + b := make([]byte, 2*len(s)) + + // A byte loop is correct because all metacharacters are ASCII. + j := 0 + for i := 0; i < len(s); i++ { + if special(s[i]) { + b[j] = '\\' + j++ + } + b[j] = s[i] + j++ + } + return string(b[0:j]) +} + +// Find matches in slice b if b is non-nil, otherwise find matches in string s. +func (re *Regexp) allMatches(s string, b []byte, n int, deliver func([]int)) { + var end int + if b == nil { + end = len(s) + } else { + end = len(b) + } + + for pos, i, prevMatchEnd := 0, 0, -1; i < n && pos <= end; { + var in input + if b == nil { + in = newInputString(s) + } else { + in = newInputBytes(b) + } + matches := re.doExecute(in, pos, re.prog.NumCap) + if len(matches) == 0 { + break + } + + accept := true + if matches[1] == pos { + // We've found an empty match. + if matches[0] == prevMatchEnd { + // We don't allow an empty match right + // after a previous match, so ignore it. + accept = false + } + var width int + // TODO: use step() + if b == nil { + _, width = utf8.DecodeRuneInString(s[pos:end]) + } else { + _, width = utf8.DecodeRune(b[pos:end]) + } + if width > 0 { + pos += width + } else { + pos = end + 1 + } + } else { + pos = matches[1] + } + prevMatchEnd = matches[1] + + if accept { + deliver(matches) + i++ + } + } +} + +// Find returns a slice holding the text of the leftmost match in b of the regular expression. +// A return value of nil indicates no match. +func (re *Regexp) Find(b []byte) []byte { + a := re.doExecute(newInputBytes(b), 0, 2) + if a == nil { + return nil + } + return b[a[0]:a[1]] +} + +// FindIndex returns a two-element slice of integers defining the location of +// the leftmost match in b of the regular expression. The match itself is at +// b[loc[0]:loc[1]]. +// A return value of nil indicates no match. +func (re *Regexp) FindIndex(b []byte) (loc []int) { + a := re.doExecute(newInputBytes(b), 0, 2) + if a == nil { + return nil + } + return a[0:2] +} + +// FindString returns a string holding the text of the leftmost match in s of the regular +// expression. If there is no match, the return value is an empty string, +// but it will also be empty if the regular expression successfully matches +// an empty string. Use FindStringIndex or FindStringSubmatch if it is +// necessary to distinguish these cases. +func (re *Regexp) FindString(s string) string { + a := re.doExecute(newInputString(s), 0, 2) + if a == nil { + return "" + } + return s[a[0]:a[1]] +} + +// FindStringIndex returns a two-element slice of integers defining the +// location of the leftmost match in s of the regular expression. The match +// itself is at s[loc[0]:loc[1]]. +// A return value of nil indicates no match. +func (re *Regexp) FindStringIndex(s string) []int { + a := re.doExecute(newInputString(s), 0, 2) + if a == nil { + return nil + } + return a[0:2] +} + +// FindReaderIndex returns a two-element slice of integers defining the +// location of the leftmost match of the regular expression in text read from +// the RuneReader. The match itself is at s[loc[0]:loc[1]]. A return +// value of nil indicates no match. +func (re *Regexp) FindReaderIndex(r io.RuneReader) []int { + a := re.doExecute(newInputReader(r), 0, 2) + if a == nil { + return nil + } + return a[0:2] +} + +// FindSubmatch returns a slice of slices holding the text of the leftmost +// match of the regular expression in b and the matches, if any, of its +// subexpressions, as defined by the 'Submatch' descriptions in the package +// comment. +// A return value of nil indicates no match. +func (re *Regexp) FindSubmatch(b []byte) [][]byte { + a := re.doExecute(newInputBytes(b), 0, re.prog.NumCap) + if a == nil { + return nil + } + ret := make([][]byte, len(a)/2) + for i := range ret { + if a[2*i] >= 0 { + ret[i] = b[a[2*i]:a[2*i+1]] + } + } + return ret +} + +// FindSubmatchIndex returns a slice holding the index pairs identifying the +// leftmost match of the regular expression in b and the matches, if any, of +// its subexpressions, as defined by the 'Submatch' and 'Index' descriptions +// in the package comment. +// A return value of nil indicates no match. +func (re *Regexp) FindSubmatchIndex(b []byte) []int { + return re.doExecute(newInputBytes(b), 0, re.prog.NumCap) +} + +// FindStringSubmatch returns a slice of strings holding the text of the +// leftmost match of the regular expression in s and the matches, if any, of +// its subexpressions, as defined by the 'Submatch' description in the +// package comment. +// A return value of nil indicates no match. +func (re *Regexp) FindStringSubmatch(s string) []string { + a := re.doExecute(newInputString(s), 0, re.prog.NumCap) + if a == nil { + return nil + } + ret := make([]string, len(a)/2) + for i := range ret { + if a[2*i] >= 0 { + ret[i] = s[a[2*i]:a[2*i+1]] + } + } + return ret +} + +// FindStringSubmatchIndex returns a slice holding the index pairs +// identifying the leftmost match of the regular expression in s and the +// matches, if any, of its subexpressions, as defined by the 'Submatch' and +// 'Index' descriptions in the package comment. +// A return value of nil indicates no match. +func (re *Regexp) FindStringSubmatchIndex(s string) []int { + return re.doExecute(newInputString(s), 0, re.prog.NumCap) +} + +// FindReaderSubmatchIndex returns a slice holding the index pairs +// identifying the leftmost match of the regular expression of text read by +// the RuneReader, and the matches, if any, of its subexpressions, as defined +// by the 'Submatch' and 'Index' descriptions in the package comment. A +// return value of nil indicates no match. +func (re *Regexp) FindReaderSubmatchIndex(r io.RuneReader) []int { + return re.doExecute(newInputReader(r), 0, re.prog.NumCap) +} + +const startSize = 10 // The size at which to start a slice in the 'All' routines. + +// FindAll is the 'All' version of Find; it returns a slice of all successive +// matches of the expression, as defined by the 'All' description in the +// package comment. +// A return value of nil indicates no match. +func (re *Regexp) FindAll(b []byte, n int) [][]byte { + if n < 0 { + n = len(b) + 1 + } + result := make([][]byte, 0, startSize) + re.allMatches("", b, n, func(match []int) { + result = append(result, b[match[0]:match[1]]) + }) + if len(result) == 0 { + return nil + } + return result +} + +// FindAllIndex is the 'All' version of FindIndex; it returns a slice of all +// successive matches of the expression, as defined by the 'All' description +// in the package comment. +// A return value of nil indicates no match. +func (re *Regexp) FindAllIndex(b []byte, n int) [][]int { + if n < 0 { + n = len(b) + 1 + } + result := make([][]int, 0, startSize) + re.allMatches("", b, n, func(match []int) { + result = append(result, match[0:2]) + }) + if len(result) == 0 { + return nil + } + return result +} + +// FindAllString is the 'All' version of FindString; it returns a slice of all +// successive matches of the expression, as defined by the 'All' description +// in the package comment. +// A return value of nil indicates no match. +func (re *Regexp) FindAllString(s string, n int) []string { + if n < 0 { + n = len(s) + 1 + } + result := make([]string, 0, startSize) + re.allMatches(s, nil, n, func(match []int) { + result = append(result, s[match[0]:match[1]]) + }) + if len(result) == 0 { + return nil + } + return result +} + +// FindAllStringIndex is the 'All' version of FindStringIndex; it returns a +// slice of all successive matches of the expression, as defined by the 'All' +// description in the package comment. +// A return value of nil indicates no match. +func (re *Regexp) FindAllStringIndex(s string, n int) [][]int { + if n < 0 { + n = len(s) + 1 + } + result := make([][]int, 0, startSize) + re.allMatches(s, nil, n, func(match []int) { + result = append(result, match[0:2]) + }) + if len(result) == 0 { + return nil + } + return result +} + +// FindAllSubmatch is the 'All' version of FindSubmatch; it returns a slice +// of all successive matches of the expression, as defined by the 'All' +// description in the package comment. +// A return value of nil indicates no match. +func (re *Regexp) FindAllSubmatch(b []byte, n int) [][][]byte { + if n < 0 { + n = len(b) + 1 + } + result := make([][][]byte, 0, startSize) + re.allMatches("", b, n, func(match []int) { + slice := make([][]byte, len(match)/2) + for j := range slice { + if match[2*j] >= 0 { + slice[j] = b[match[2*j]:match[2*j+1]] + } + } + result = append(result, slice) + }) + if len(result) == 0 { + return nil + } + return result +} + +// FindAllSubmatchIndex is the 'All' version of FindSubmatchIndex; it returns +// a slice of all successive matches of the expression, as defined by the +// 'All' description in the package comment. +// A return value of nil indicates no match. +func (re *Regexp) FindAllSubmatchIndex(b []byte, n int) [][]int { + if n < 0 { + n = len(b) + 1 + } + result := make([][]int, 0, startSize) + re.allMatches("", b, n, func(match []int) { + result = append(result, match) + }) + if len(result) == 0 { + return nil + } + return result +} + +// FindAllStringSubmatch is the 'All' version of FindStringSubmatch; it +// returns a slice of all successive matches of the expression, as defined by +// the 'All' description in the package comment. +// A return value of nil indicates no match. +func (re *Regexp) FindAllStringSubmatch(s string, n int) [][]string { + if n < 0 { + n = len(s) + 1 + } + result := make([][]string, 0, startSize) + re.allMatches(s, nil, n, func(match []int) { + slice := make([]string, len(match)/2) + for j := range slice { + if match[2*j] >= 0 { + slice[j] = s[match[2*j]:match[2*j+1]] + } + } + result = append(result, slice) + }) + if len(result) == 0 { + return nil + } + return result +} + +// FindAllStringSubmatchIndex is the 'All' version of +// FindStringSubmatchIndex; it returns a slice of all successive matches of +// the expression, as defined by the 'All' description in the package +// comment. +// A return value of nil indicates no match. +func (re *Regexp) FindAllStringSubmatchIndex(s string, n int) [][]int { + if n < 0 { + n = len(s) + 1 + } + result := make([][]int, 0, startSize) + re.allMatches(s, nil, n, func(match []int) { + result = append(result, match) + }) + if len(result) == 0 { + return nil + } + return result +} diff --git a/libgo/go/exp/regexp/syntax/compile.go b/libgo/go/exp/regexp/syntax/compile.go new file mode 100644 index 00000000000..5ea2425c3aa --- /dev/null +++ b/libgo/go/exp/regexp/syntax/compile.go @@ -0,0 +1,269 @@ +package syntax + +import ( + "os" + "unicode" +) + +// A patchList is a list of instruction pointers that need to be filled in (patched). +// Because the pointers haven't been filled in yet, we can reuse their storage +// to hold the list. It's kind of sleazy, but works well in practice. +// See http://swtch.com/~rsc/regexp/regexp1.html for inspiration. +// +// These aren't really pointers: they're integers, so we can reinterpret them +// this way without using package unsafe. A value l denotes +// p.inst[l>>1].Out (l&1==0) or .Arg (l&1==1). +// l == 0 denotes the empty list, okay because we start every program +// with a fail instruction, so we'll never want to point at its output link. +type patchList uint32 + +func (l patchList) next(p *Prog) patchList { + i := &p.Inst[l>>1] + if l&1 == 0 { + return patchList(i.Out) + } + return patchList(i.Arg) +} + +func (l patchList) patch(p *Prog, val uint32) { + for l != 0 { + i := &p.Inst[l>>1] + if l&1 == 0 { + l = patchList(i.Out) + i.Out = val + } else { + l = patchList(i.Arg) + i.Arg = val + } + } +} + +func (l1 patchList) append(p *Prog, l2 patchList) patchList { + if l1 == 0 { + return l2 + } + if l2 == 0 { + return l1 + } + + last := l1 + for { + next := last.next(p) + if next == 0 { + break + } + last = next + } + + i := &p.Inst[last>>1] + if last&1 == 0 { + i.Out = uint32(l2) + } else { + i.Arg = uint32(l2) + } + return l1 +} + +// A frag represents a compiled program fragment. +type frag struct { + i uint32 // index of first instruction + out patchList // where to record end instruction +} + +type compiler struct { + p *Prog +} + +// Compile compiles the regexp into a program to be executed. +func Compile(re *Regexp) (*Prog, os.Error) { + var c compiler + c.init() + f := c.compile(re) + f.out.patch(c.p, c.inst(InstMatch).i) + c.p.Start = int(f.i) + return c.p, nil +} + +func (c *compiler) init() { + c.p = new(Prog) + c.p.NumCap = 2 // implicit ( and ) for whole match $0 + c.inst(InstFail) +} + +var anyRuneNotNL = []int{0, '\n' - 1, '\n' - 1, unicode.MaxRune} +var anyRune = []int{0, unicode.MaxRune} + +func (c *compiler) compile(re *Regexp) frag { + switch re.Op { + case OpNoMatch: + return c.fail() + case OpEmptyMatch: + return c.nop() + case OpLiteral: + if len(re.Rune) == 0 { + return c.nop() + } + var f frag + for j := range re.Rune { + f1 := c.rune(re.Rune[j : j+1]) + if j == 0 { + f = f1 + } else { + f = c.cat(f, f1) + } + } + return f + case OpCharClass: + return c.rune(re.Rune) + case OpAnyCharNotNL: + return c.rune(anyRuneNotNL) + case OpAnyChar: + return c.rune(anyRune) + case OpBeginLine: + return c.empty(EmptyBeginLine) + case OpEndLine: + return c.empty(EmptyEndLine) + case OpBeginText: + return c.empty(EmptyBeginText) + case OpEndText: + return c.empty(EmptyEndText) + case OpWordBoundary: + return c.empty(EmptyWordBoundary) + case OpNoWordBoundary: + return c.empty(EmptyNoWordBoundary) + case OpCapture: + bra := c.cap(uint32(re.Cap << 1)) + sub := c.compile(re.Sub[0]) + ket := c.cap(uint32(re.Cap<<1 | 1)) + return c.cat(c.cat(bra, sub), ket) + case OpStar: + return c.star(c.compile(re.Sub[0]), re.Flags&NonGreedy != 0) + case OpPlus: + return c.plus(c.compile(re.Sub[0]), re.Flags&NonGreedy != 0) + case OpQuest: + return c.quest(c.compile(re.Sub[0]), re.Flags&NonGreedy != 0) + case OpConcat: + if len(re.Sub) == 0 { + return c.nop() + } + var f frag + for i, sub := range re.Sub { + if i == 0 { + f = c.compile(sub) + } else { + f = c.cat(f, c.compile(sub)) + } + } + return f + case OpAlternate: + var f frag + for _, sub := range re.Sub { + f = c.alt(f, c.compile(sub)) + } + return f + } + panic("regexp: unhandled case in compile") +} + +func (c *compiler) inst(op InstOp) frag { + // TODO: impose length limit + f := frag{i: uint32(len(c.p.Inst))} + c.p.Inst = append(c.p.Inst, Inst{Op: op}) + return f +} + +func (c *compiler) nop() frag { + f := c.inst(InstNop) + f.out = patchList(f.i << 1) + return f +} + +func (c *compiler) fail() frag { + return frag{} +} + +func (c *compiler) cap(arg uint32) frag { + f := c.inst(InstCapture) + f.out = patchList(f.i << 1) + c.p.Inst[f.i].Arg = arg + + if c.p.NumCap < int(arg)+1 { + c.p.NumCap = int(arg) + 1 + } + return f +} + +func (c *compiler) cat(f1, f2 frag) frag { + // concat of failure is failure + if f1.i == 0 || f2.i == 0 { + return frag{} + } + + // TODO: elide nop + + f1.out.patch(c.p, f2.i) + return frag{f1.i, f2.out} +} + +func (c *compiler) alt(f1, f2 frag) frag { + // alt of failure is other + if f1.i == 0 { + return f2 + } + if f2.i == 0 { + return f1 + } + + f := c.inst(InstAlt) + i := &c.p.Inst[f.i] + i.Out = f1.i + i.Arg = f2.i + f.out = f1.out.append(c.p, f2.out) + return f +} + +func (c *compiler) quest(f1 frag, nongreedy bool) frag { + f := c.inst(InstAlt) + i := &c.p.Inst[f.i] + if nongreedy { + i.Arg = f1.i + f.out = patchList(f.i << 1) + } else { + i.Out = f1.i + f.out = patchList(f.i<<1 | 1) + } + f.out = f.out.append(c.p, f1.out) + return f +} + +func (c *compiler) star(f1 frag, nongreedy bool) frag { + f := c.inst(InstAlt) + i := &c.p.Inst[f.i] + if nongreedy { + i.Arg = f1.i + f.out = patchList(f.i << 1) + } else { + i.Out = f1.i + f.out = patchList(f.i<<1 | 1) + } + f1.out.patch(c.p, f.i) + return f +} + +func (c *compiler) plus(f1 frag, nongreedy bool) frag { + return frag{f1.i, c.star(f1, nongreedy).out} +} + +func (c *compiler) empty(op EmptyOp) frag { + f := c.inst(InstEmptyWidth) + c.p.Inst[f.i].Arg = uint32(op) + f.out = patchList(f.i << 1) + return f +} + +func (c *compiler) rune(rune []int) frag { + f := c.inst(InstRune) + c.p.Inst[f.i].Rune = rune + f.out = patchList(f.i << 1) + return f +} diff --git a/libgo/go/exp/regexp/syntax/parse.go b/libgo/go/exp/regexp/syntax/parse.go new file mode 100644 index 00000000000..4eed182687b --- /dev/null +++ b/libgo/go/exp/regexp/syntax/parse.go @@ -0,0 +1,1797 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package syntax + +import ( + "os" + "sort" + "strings" + "unicode" + "utf8" +) + +// An Error describes a failure to parse a regular expression +// and gives the offending expression. +type Error struct { + Code ErrorCode + Expr string +} + +func (e *Error) String() string { + return "error parsing regexp: " + e.Code.String() + ": `" + e.Expr + "`" +} + +// An ErrorCode describes a failure to parse a regular expression. +type ErrorCode string + +const ( + // Unexpected error + ErrInternalError ErrorCode = "regexp/syntax: internal error" + + // Parse errors + ErrInvalidCharClass ErrorCode = "invalid character class" + ErrInvalidCharRange ErrorCode = "invalid character class range" + ErrInvalidEscape ErrorCode = "invalid escape sequence" + ErrInvalidNamedCapture ErrorCode = "invalid named capture" + ErrInvalidPerlOp ErrorCode = "invalid or unsupported Perl syntax" + ErrInvalidRepeatOp ErrorCode = "invalid nested repetition operator" + ErrInvalidRepeatSize ErrorCode = "invalid repeat count" + ErrInvalidUTF8 ErrorCode = "invalid UTF-8" + ErrMissingBracket ErrorCode = "missing closing ]" + ErrMissingParen ErrorCode = "missing closing )" + ErrMissingRepeatArgument ErrorCode = "missing argument to repetition operator" + ErrTrailingBackslash ErrorCode = "trailing backslash at end of expression" +) + +func (e ErrorCode) String() string { + return string(e) +} + +// Flags control the behavior of the parser and record information about regexp context. +type Flags uint16 + +const ( + FoldCase Flags = 1 << iota // case-insensitive match + Literal // treat pattern as literal string + ClassNL // allow character classes like [^a-z] and [[:space:]] to match newline + DotNL // allow . to match newline + OneLine // treat ^ and $ as only matching at beginning and end of text + NonGreedy // make repetition operators default to non-greedy + PerlX // allow Perl extensions + UnicodeGroups // allow \p{Han}, \P{Han} for Unicode group and negation + WasDollar // regexp OpEndText was $, not \z + Simple // regexp contains no counted repetition + + MatchNL = ClassNL | DotNL + + Perl = ClassNL | OneLine | PerlX | UnicodeGroups // as close to Perl as possible + POSIX Flags = 0 // POSIX syntax +) + +// Pseudo-ops for parsing stack. +const ( + opLeftParen = opPseudo + iota + opVerticalBar +) + +type parser struct { + flags Flags // parse mode flags + stack []*Regexp // stack of parsed expressions + free *Regexp + numCap int // number of capturing groups seen + wholeRegexp string + tmpClass []int // temporary char class work space +} + +func (p *parser) newRegexp(op Op) *Regexp { + re := p.free + if re != nil { + p.free = re.Sub0[0] + *re = Regexp{} + } else { + re = new(Regexp) + } + re.Op = op + return re +} + +func (p *parser) reuse(re *Regexp) { + re.Sub0[0] = p.free + p.free = re +} + +// Parse stack manipulation. + +// push pushes the regexp re onto the parse stack and returns the regexp. +func (p *parser) push(re *Regexp) *Regexp { + if re.Op == OpCharClass && len(re.Rune) == 2 && re.Rune[0] == re.Rune[1] { + // Single rune. + if p.maybeConcat(re.Rune[0], p.flags&^FoldCase) { + return nil + } + re.Op = OpLiteral + re.Rune = re.Rune[:1] + re.Flags = p.flags &^ FoldCase + } else if re.Op == OpCharClass && len(re.Rune) == 4 && + re.Rune[0] == re.Rune[1] && re.Rune[2] == re.Rune[3] && + unicode.SimpleFold(re.Rune[0]) == re.Rune[2] && + unicode.SimpleFold(re.Rune[2]) == re.Rune[0] || + re.Op == OpCharClass && len(re.Rune) == 2 && + re.Rune[0]+1 == re.Rune[1] && + unicode.SimpleFold(re.Rune[0]) == re.Rune[1] && + unicode.SimpleFold(re.Rune[1]) == re.Rune[0] { + // Case-insensitive rune like [Aa] or [Δδ]. + if p.maybeConcat(re.Rune[0], p.flags|FoldCase) { + return nil + } + + // Rewrite as (case-insensitive) literal. + re.Op = OpLiteral + re.Rune = re.Rune[:1] + re.Flags = p.flags | FoldCase + } else { + // Incremental concatenation. + p.maybeConcat(-1, 0) + } + + p.stack = append(p.stack, re) + return re +} + +// maybeConcat implements incremental concatenation +// of literal runes into string nodes. The parser calls this +// before each push, so only the top fragment of the stack +// might need processing. Since this is called before a push, +// the topmost literal is no longer subject to operators like * +// (Otherwise ab* would turn into (ab)*.) +// If r >= 0 and there's a node left over, maybeConcat uses it +// to push r with the given flags. +// maybeConcat reports whether r was pushed. +func (p *parser) maybeConcat(r int, flags Flags) bool { + n := len(p.stack) + if n < 2 { + return false + } + + re1 := p.stack[n-1] + re2 := p.stack[n-2] + if re1.Op != OpLiteral || re2.Op != OpLiteral || re1.Flags&FoldCase != re2.Flags&FoldCase { + return false + } + + // Push re1 into re2. + re2.Rune = append(re2.Rune, re1.Rune...) + + // Reuse re1 if possible. + if r >= 0 { + re1.Rune = re1.Rune0[:1] + re1.Rune[0] = r + re1.Flags = flags + return true + } + + p.stack = p.stack[:n-1] + p.reuse(re1) + return false // did not push r +} + +// newLiteral returns a new OpLiteral Regexp with the given flags +func (p *parser) newLiteral(r int, flags Flags) *Regexp { + re := p.newRegexp(OpLiteral) + re.Flags = flags + re.Rune0[0] = r + re.Rune = re.Rune0[:1] + return re +} + +// literal pushes a literal regexp for the rune r on the stack +// and returns that regexp. +func (p *parser) literal(r int) { + p.push(p.newLiteral(r, p.flags)) +} + +// op pushes a regexp with the given op onto the stack +// and returns that regexp. +func (p *parser) op(op Op) *Regexp { + re := p.newRegexp(op) + re.Flags = p.flags + return p.push(re) +} + +// repeat replaces the top stack element with itself repeated +// according to op. +func (p *parser) repeat(op Op, min, max int, opstr, t, lastRepeat string) (string, os.Error) { + flags := p.flags + if p.flags&PerlX != 0 { + if len(t) > 0 && t[0] == '?' { + t = t[1:] + flags ^= NonGreedy + } + if lastRepeat != "" { + // In Perl it is not allowed to stack repetition operators: + // a** is a syntax error, not a doubled star, and a++ means + // something else entirely, which we don't support! + return "", &Error{ErrInvalidRepeatOp, lastRepeat[:len(lastRepeat)-len(t)]} + } + } + n := len(p.stack) + if n == 0 { + return "", &Error{ErrMissingRepeatArgument, opstr} + } + sub := p.stack[n-1] + re := p.newRegexp(op) + re.Min = min + re.Max = max + re.Flags = flags + re.Sub = re.Sub0[:1] + re.Sub[0] = sub + p.stack[n-1] = re + return t, nil +} + +// concat replaces the top of the stack (above the topmost '|' or '(') with its concatenation. +func (p *parser) concat() *Regexp { + p.maybeConcat(-1, 0) + + // Scan down to find pseudo-operator | or (. + i := len(p.stack) + for i > 0 && p.stack[i-1].Op < opPseudo { + i-- + } + subs := p.stack[i:] + p.stack = p.stack[:i] + + // Empty concatenation is special case. + if len(subs) == 0 { + return p.push(p.newRegexp(OpEmptyMatch)) + } + + return p.push(p.collapse(subs, OpConcat)) +} + +// alternate replaces the top of the stack (above the topmost '(') with its alternation. +func (p *parser) alternate() *Regexp { + // Scan down to find pseudo-operator (. + // There are no | above (. + i := len(p.stack) + for i > 0 && p.stack[i-1].Op < opPseudo { + i-- + } + subs := p.stack[i:] + p.stack = p.stack[:i] + + // Make sure top class is clean. + // All the others already are (see swapVerticalBar). + if len(subs) > 0 { + cleanAlt(subs[len(subs)-1]) + } + + // Empty alternate is special case + // (shouldn't happen but easy to handle). + if len(subs) == 0 { + return p.push(p.newRegexp(OpNoMatch)) + } + + return p.push(p.collapse(subs, OpAlternate)) +} + +// cleanAlt cleans re for eventual inclusion in an alternation. +func cleanAlt(re *Regexp) { + switch re.Op { + case OpCharClass: + re.Rune = cleanClass(&re.Rune) + if len(re.Rune) == 2 && re.Rune[0] == 0 && re.Rune[1] == unicode.MaxRune { + re.Rune = nil + re.Op = OpAnyChar + return + } + if len(re.Rune) == 4 && re.Rune[0] == 0 && re.Rune[1] == '\n'-1 && re.Rune[2] == '\n'+1 && re.Rune[3] == unicode.MaxRune { + re.Rune = nil + re.Op = OpAnyCharNotNL + return + } + if cap(re.Rune)-len(re.Rune) > 100 { + // re.Rune will not grow any more. + // Make a copy or inline to reclaim storage. + re.Rune = append(re.Rune0[:0], re.Rune...) + } + } +} + +// collapse returns the result of applying op to sub. +// If sub contains op nodes, they all get hoisted up +// so that there is never a concat of a concat or an +// alternate of an alternate. +func (p *parser) collapse(subs []*Regexp, op Op) *Regexp { + if len(subs) == 1 { + return subs[0] + } + re := p.newRegexp(op) + re.Sub = re.Sub0[:0] + for _, sub := range subs { + if sub.Op == op { + re.Sub = append(re.Sub, sub.Sub...) + p.reuse(sub) + } else { + re.Sub = append(re.Sub, sub) + } + } + if op == OpAlternate { + re.Sub = p.factor(re.Sub, re.Flags) + if len(re.Sub) == 1 { + old := re + re = re.Sub[0] + p.reuse(old) + } + } + return re +} + +// factor factors common prefixes from the alternation list sub. +// It returns a replacement list that reuses the same storage and +// frees (passes to p.reuse) any removed *Regexps. +// +// For example, +// ABC|ABD|AEF|BCX|BCY +// simplifies by literal prefix extraction to +// A(B(C|D)|EF)|BC(X|Y) +// which simplifies by character class introduction to +// A(B[CD]|EF)|BC[XY] +// +func (p *parser) factor(sub []*Regexp, flags Flags) []*Regexp { + if len(sub) < 2 { + return sub + } + + // Round 1: Factor out common literal prefixes. + var str []int + var strflags Flags + start := 0 + out := sub[:0] + for i := 0; i <= len(sub); i++ { + // Invariant: the Regexps that were in sub[0:start] have been + // used or marked for reuse, and the slice space has been reused + // for out (len(out) <= start). + // + // Invariant: sub[start:i] consists of regexps that all begin + // with str as modified by strflags. + var istr []int + var iflags Flags + if i < len(sub) { + istr, iflags = p.leadingString(sub[i]) + if iflags == strflags { + same := 0 + for same < len(str) && same < len(istr) && str[same] == istr[same] { + same++ + } + if same > 0 { + // Matches at least one rune in current range. + // Keep going around. + str = str[:same] + continue + } + } + } + + // Found end of a run with common leading literal string: + // sub[start:i] all begin with str[0:len(str)], but sub[i] + // does not even begin with str[0]. + // + // Factor out common string and append factored expression to out. + if i == start { + // Nothing to do - run of length 0. + } else if i == start+1 { + // Just one: don't bother factoring. + out = append(out, sub[start]) + } else { + // Construct factored form: prefix(suffix1|suffix2|...) + prefix := p.newRegexp(OpLiteral) + prefix.Flags = strflags + prefix.Rune = append(prefix.Rune[:0], str...) + + for j := start; j < i; j++ { + sub[j] = p.removeLeadingString(sub[j], len(str)) + } + suffix := p.collapse(sub[start:i], OpAlternate) // recurse + + re := p.newRegexp(OpConcat) + re.Sub = append(re.Sub[:0], prefix, suffix) + out = append(out, re) + } + + // Prepare for next iteration. + start = i + str = istr + strflags = iflags + } + sub = out + + // Round 2: Factor out common complex prefixes, + // just the first piece of each concatenation, + // whatever it is. This is good enough a lot of the time. + start = 0 + out = sub[:0] + var first *Regexp + for i := 0; i <= len(sub); i++ { + // Invariant: the Regexps that were in sub[0:start] have been + // used or marked for reuse, and the slice space has been reused + // for out (len(out) <= start). + // + // Invariant: sub[start:i] consists of regexps that all begin + // with str as modified by strflags. + var ifirst *Regexp + if i < len(sub) { + ifirst = p.leadingRegexp(sub[i]) + if first != nil && first.Equal(ifirst) { + continue + } + } + + // Found end of a run with common leading regexp: + // sub[start:i] all begin with first but sub[i] does not. + // + // Factor out common regexp and append factored expression to out. + if i == start { + // Nothing to do - run of length 0. + } else if i == start+1 { + // Just one: don't bother factoring. + out = append(out, sub[start]) + } else { + // Construct factored form: prefix(suffix1|suffix2|...) + prefix := first + + for j := start; j < i; j++ { + reuse := j != start // prefix came from sub[start] + sub[j] = p.removeLeadingRegexp(sub[j], reuse) + } + suffix := p.collapse(sub[start:i], OpAlternate) // recurse + + re := p.newRegexp(OpConcat) + re.Sub = append(re.Sub[:0], prefix, suffix) + out = append(out, re) + } + + // Prepare for next iteration. + start = i + first = ifirst + } + sub = out + + // Round 3: Collapse runs of single literals into character classes. + start = 0 + out = sub[:0] + for i := 0; i <= len(sub); i++ { + // Invariant: the Regexps that were in sub[0:start] have been + // used or marked for reuse, and the slice space has been reused + // for out (len(out) <= start). + // + // Invariant: sub[start:i] consists of regexps that are either + // literal runes or character classes. + if i < len(sub) && isCharClass(sub[i]) { + continue + } + + // sub[i] is not a char or char class; + // emit char class for sub[start:i]... + if i == start { + // Nothing to do - run of length 0. + } else if i == start+1 { + out = append(out, sub[start]) + } else { + // Make new char class. + // Start with most complex regexp in sub[start]. + max := start + for j := start + 1; j < i; j++ { + if sub[max].Op < sub[j].Op || sub[max].Op == sub[j].Op && len(sub[max].Rune) < len(sub[j].Rune) { + max = j + } + } + sub[start], sub[max] = sub[max], sub[start] + + for j := start + 1; j < i; j++ { + mergeCharClass(sub[start], sub[j]) + p.reuse(sub[j]) + } + cleanAlt(sub[start]) + out = append(out, sub[start]) + } + + // ... and then emit sub[i]. + if i < len(sub) { + out = append(out, sub[i]) + } + start = i + 1 + } + sub = out + + // Round 4: Collapse runs of empty matches into a single empty match. + start = 0 + out = sub[:0] + for i := range sub { + if i+1 < len(sub) && sub[i].Op == OpEmptyMatch && sub[i+1].Op == OpEmptyMatch { + continue + } + out = append(out, sub[i]) + } + sub = out + + return sub +} + +// leadingString returns the leading literal string that re begins with. +// The string refers to storage in re or its children. +func (p *parser) leadingString(re *Regexp) ([]int, Flags) { + if re.Op == OpConcat && len(re.Sub) > 0 { + re = re.Sub[0] + } + if re.Op != OpLiteral { + return nil, 0 + } + return re.Rune, re.Flags & FoldCase +} + +// removeLeadingString removes the first n leading runes +// from the beginning of re. It returns the replacement for re. +func (p *parser) removeLeadingString(re *Regexp, n int) *Regexp { + if re.Op == OpConcat && len(re.Sub) > 0 { + // Removing a leading string in a concatenation + // might simplify the concatenation. + sub := re.Sub[0] + sub = p.removeLeadingString(sub, n) + re.Sub[0] = sub + if sub.Op == OpEmptyMatch { + p.reuse(sub) + switch len(re.Sub) { + case 0, 1: + // Impossible but handle. + re.Op = OpEmptyMatch + re.Sub = nil + case 2: + old := re + re = re.Sub[1] + p.reuse(old) + default: + copy(re.Sub, re.Sub[1:]) + re.Sub = re.Sub[:len(re.Sub)-1] + } + } + return re + } + + if re.Op == OpLiteral { + re.Rune = re.Rune[:copy(re.Rune, re.Rune[n:])] + if len(re.Rune) == 0 { + re.Op = OpEmptyMatch + } + } + return re +} + +// leadingRegexp returns the leading regexp that re begins with. +// The regexp refers to storage in re or its children. +func (p *parser) leadingRegexp(re *Regexp) *Regexp { + if re.Op == OpEmptyMatch { + return nil + } + if re.Op == OpConcat && len(re.Sub) > 0 { + sub := re.Sub[0] + if sub.Op == OpEmptyMatch { + return nil + } + return sub + } + return re +} + +// removeLeadingRegexp removes the leading regexp in re. +// It returns the replacement for re. +// If reuse is true, it passes the removed regexp (if no longer needed) to p.reuse. +func (p *parser) removeLeadingRegexp(re *Regexp, reuse bool) *Regexp { + if re.Op == OpConcat && len(re.Sub) > 0 { + if reuse { + p.reuse(re.Sub[0]) + } + re.Sub = re.Sub[:copy(re.Sub, re.Sub[1:])] + switch len(re.Sub) { + case 0: + re.Op = OpEmptyMatch + re.Sub = nil + case 1: + old := re + re = re.Sub[0] + p.reuse(old) + } + return re + } + re.Op = OpEmptyMatch + return re +} + +func literalRegexp(s string, flags Flags) *Regexp { + re := &Regexp{Op: OpLiteral} + re.Flags = flags + re.Rune = re.Rune0[:0] // use local storage for small strings + for _, c := range s { + if len(re.Rune) >= cap(re.Rune) { + // string is too long to fit in Rune0. let Go handle it + re.Rune = []int(s) + break + } + re.Rune = append(re.Rune, c) + } + return re +} + +// Parsing. + +func Parse(s string, flags Flags) (*Regexp, os.Error) { + if flags&Literal != 0 { + // Trivial parser for literal string. + if err := checkUTF8(s); err != nil { + return nil, err + } + return literalRegexp(s, flags), nil + } + + // Otherwise, must do real work. + var ( + p parser + err os.Error + c int + op Op + lastRepeat string + min, max int + ) + p.flags = flags + p.wholeRegexp = s + t := s + for t != "" { + repeat := "" + BigSwitch: + switch t[0] { + default: + if c, t, err = nextRune(t); err != nil { + return nil, err + } + p.literal(c) + + case '(': + if p.flags&PerlX != 0 && len(t) >= 2 && t[1] == '?' { + // Flag changes and non-capturing groups. + if t, err = p.parsePerlFlags(t); err != nil { + return nil, err + } + break + } + p.numCap++ + p.op(opLeftParen).Cap = p.numCap + t = t[1:] + case '|': + if err = p.parseVerticalBar(); err != nil { + return nil, err + } + t = t[1:] + case ')': + if err = p.parseRightParen(); err != nil { + return nil, err + } + t = t[1:] + case '^': + if p.flags&OneLine != 0 { + p.op(OpBeginText) + } else { + p.op(OpBeginLine) + } + t = t[1:] + case '$': + if p.flags&OneLine != 0 { + p.op(OpEndText).Flags |= WasDollar + } else { + p.op(OpEndLine) + } + t = t[1:] + case '.': + if p.flags&DotNL != 0 { + p.op(OpAnyChar) + } else { + p.op(OpAnyCharNotNL) + } + t = t[1:] + case '[': + if t, err = p.parseClass(t); err != nil { + return nil, err + } + case '*', '+', '?': + switch t[0] { + case '*': + op = OpStar + case '+': + op = OpPlus + case '?': + op = OpQuest + } + if t, err = p.repeat(op, min, max, t[:1], t[1:], lastRepeat); err != nil { + return nil, err + } + case '{': + op = OpRepeat + min, max, tt, ok := p.parseRepeat(t) + if !ok { + // If the repeat cannot be parsed, { is a literal. + p.literal('{') + t = t[1:] + break + } + if t, err = p.repeat(op, min, max, t[:len(t)-len(tt)], tt, lastRepeat); err != nil { + return nil, err + } + case '\\': + if p.flags&PerlX != 0 && len(t) >= 2 { + switch t[1] { + case 'A': + p.op(OpBeginText) + t = t[2:] + break BigSwitch + case 'b': + p.op(OpWordBoundary) + t = t[2:] + break BigSwitch + case 'B': + p.op(OpNoWordBoundary) + t = t[2:] + break BigSwitch + case 'C': + // any byte; not supported + return nil, &Error{ErrInvalidEscape, t[:2]} + case 'Q': + // \Q ... \E: the ... is always literals + var lit string + if i := strings.Index(t, `\E`); i < 0 { + lit = t[2:] + t = "" + } else { + lit = t[2:i] + t = t[i+2:] + } + p.push(literalRegexp(lit, p.flags)) + break BigSwitch + case 'z': + p.op(OpEndText) + t = t[2:] + break BigSwitch + } + } + + re := p.newRegexp(OpCharClass) + re.Flags = p.flags + + // Look for Unicode character group like \p{Han} + if len(t) >= 2 && (t[1] == 'p' || t[1] == 'P') { + r, rest, err := p.parseUnicodeClass(t, re.Rune0[:0]) + if err != nil { + return nil, err + } + if r != nil { + re.Rune = r + t = rest + p.push(re) + break BigSwitch + } + } + + // Perl character class escape. + if r, rest := p.parsePerlClassEscape(t, re.Rune0[:0]); r != nil { + re.Rune = r + t = rest + p.push(re) + break BigSwitch + } + p.reuse(re) + + // Ordinary single-character escape. + if c, t, err = p.parseEscape(t); err != nil { + return nil, err + } + p.literal(c) + } + lastRepeat = repeat + } + + p.concat() + if p.swapVerticalBar() { + // pop vertical bar + p.stack = p.stack[:len(p.stack)-1] + } + p.alternate() + + n := len(p.stack) + if n != 1 { + return nil, &Error{ErrMissingParen, s} + } + return p.stack[0], nil +} + +// parseRepeat parses {min} (max=min) or {min,} (max=-1) or {min,max}. +// If s is not of that form, it returns ok == false. +func (p *parser) parseRepeat(s string) (min, max int, rest string, ok bool) { + if s == "" || s[0] != '{' { + return + } + s = s[1:] + if min, s, ok = p.parseInt(s); !ok { + return + } + if s == "" { + return + } + if s[0] != ',' { + max = min + } else { + s = s[1:] + if s == "" { + return + } + if s[0] == '}' { + max = -1 + } else if max, s, ok = p.parseInt(s); !ok { + return + } + } + if s == "" || s[0] != '}' { + return + } + rest = s[1:] + ok = true + return +} + +// parsePerlFlags parses a Perl flag setting or non-capturing group or both, +// like (?i) or (?: or (?i:. It removes the prefix from s and updates the parse state. +// The caller must have ensured that s begins with "(?". +func (p *parser) parsePerlFlags(s string) (rest string, err os.Error) { + t := s + + // Check for named captures, first introduced in Python's regexp library. + // As usual, there are three slightly different syntaxes: + // + // (?P<name>expr) the original, introduced by Python + // (?<name>expr) the .NET alteration, adopted by Perl 5.10 + // (?'name'expr) another .NET alteration, adopted by Perl 5.10 + // + // Perl 5.10 gave in and implemented the Python version too, + // but they claim that the last two are the preferred forms. + // PCRE and languages based on it (specifically, PHP and Ruby) + // support all three as well. EcmaScript 4 uses only the Python form. + // + // In both the open source world (via Code Search) and the + // Google source tree, (?P<expr>name) is the dominant form, + // so that's the one we implement. One is enough. + if len(t) > 4 && t[2] == 'P' && t[3] == '<' { + // Pull out name. + end := strings.IndexRune(t, '>') + if end < 0 { + if err = checkUTF8(t); err != nil { + return "", err + } + return "", &Error{ErrInvalidNamedCapture, s} + } + + capture := t[:end+1] // "(?P<name>" + name := t[4:end] // "name" + if err = checkUTF8(name); err != nil { + return "", err + } + if !isValidCaptureName(name) { + return "", &Error{ErrInvalidNamedCapture, capture} + } + + // Like ordinary capture, but named. + p.numCap++ + re := p.op(opLeftParen) + re.Cap = p.numCap + re.Name = name + return t[end+1:], nil + } + + // Non-capturing group. Might also twiddle Perl flags. + var c int + t = t[2:] // skip (? + flags := p.flags + sign := +1 + sawFlag := false +Loop: + for t != "" { + if c, t, err = nextRune(t); err != nil { + return "", err + } + switch c { + default: + break Loop + + // Flags. + case 'i': + flags |= FoldCase + sawFlag = true + case 'm': + flags &^= OneLine + sawFlag = true + case 's': + flags |= DotNL + sawFlag = true + case 'U': + flags |= NonGreedy + sawFlag = true + + // Switch to negation. + case '-': + if sign < 0 { + break Loop + } + sign = -1 + // Invert flags so that | above turn into &^ and vice versa. + // We'll invert flags again before using it below. + flags = ^flags + sawFlag = false + + // End of flags, starting group or not. + case ':', ')': + if sign < 0 { + if !sawFlag { + break Loop + } + flags = ^flags + } + if c == ':' { + // Open new group + p.op(opLeftParen) + } + p.flags = flags + return t, nil + } + } + + return "", &Error{ErrInvalidPerlOp, s[:len(s)-len(t)]} +} + +// isValidCaptureName reports whether name +// is a valid capture name: [A-Za-z0-9_]+. +// PCRE limits names to 32 bytes. +// Python rejects names starting with digits. +// We don't enforce either of those. +func isValidCaptureName(name string) bool { + if name == "" { + return false + } + for _, c := range name { + if c != '_' && !isalnum(c) { + return false + } + } + return true +} + +// parseInt parses a decimal integer. +func (p *parser) parseInt(s string) (n int, rest string, ok bool) { + if s == "" || s[0] < '0' || '9' < s[0] { + return + } + // Disallow leading zeros. + if len(s) >= 2 && s[0] == '0' && '0' <= s[1] && s[1] <= '9' { + return + } + for s != "" && '0' <= s[0] && s[0] <= '9' { + // Avoid overflow. + if n >= 1e8 { + return + } + n = n*10 + int(s[0]) - '0' + s = s[1:] + } + rest = s + ok = true + return +} + +// can this be represented as a character class? +// single-rune literal string, char class, ., and .|\n. +func isCharClass(re *Regexp) bool { + return re.Op == OpLiteral && len(re.Rune) == 1 || + re.Op == OpCharClass || + re.Op == OpAnyCharNotNL || + re.Op == OpAnyChar +} + +// does re match r? +func matchRune(re *Regexp, r int) bool { + switch re.Op { + case OpLiteral: + return len(re.Rune) == 1 && re.Rune[0] == r + case OpCharClass: + for i := 0; i < len(re.Rune); i += 2 { + if re.Rune[i] <= r && r <= re.Rune[i+1] { + return true + } + } + return false + case OpAnyCharNotNL: + return r != '\n' + case OpAnyChar: + return true + } + return false +} + +// parseVerticalBar handles a | in the input. +func (p *parser) parseVerticalBar() os.Error { + p.concat() + + // The concatenation we just parsed is on top of the stack. + // If it sits above an opVerticalBar, swap it below + // (things below an opVerticalBar become an alternation). + // Otherwise, push a new vertical bar. + if !p.swapVerticalBar() { + p.op(opVerticalBar) + } + + return nil +} + +// mergeCharClass makes dst = dst|src. +// The caller must ensure that dst.Op >= src.Op, +// to reduce the amount of copying. +func mergeCharClass(dst, src *Regexp) { + switch dst.Op { + case OpAnyChar: + // src doesn't add anything. + case OpAnyCharNotNL: + // src might add \n + if matchRune(src, '\n') { + dst.Op = OpAnyChar + } + case OpCharClass: + // src is simpler, so either literal or char class + if src.Op == OpLiteral { + dst.Rune = appendRange(dst.Rune, src.Rune[0], src.Rune[0]) + } else { + dst.Rune = appendClass(dst.Rune, src.Rune) + } + case OpLiteral: + // both literal + if src.Rune[0] == dst.Rune[0] { + break + } + dst.Op = OpCharClass + dst.Rune = append(dst.Rune, dst.Rune[0]) + dst.Rune = appendRange(dst.Rune, src.Rune[0], src.Rune[0]) + } +} + +// If the top of the stack is an element followed by an opVerticalBar +// swapVerticalBar swaps the two and returns true. +// Otherwise it returns false. +func (p *parser) swapVerticalBar() bool { + // If above and below vertical bar are literal or char class, + // can merge into a single char class. + n := len(p.stack) + if n >= 3 && p.stack[n-2].Op == opVerticalBar && isCharClass(p.stack[n-1]) && isCharClass(p.stack[n-3]) { + re1 := p.stack[n-1] + re3 := p.stack[n-3] + // Make re3 the more complex of the two. + if re1.Op > re3.Op { + re1, re3 = re3, re1 + p.stack[n-3] = re3 + } + mergeCharClass(re3, re1) + p.reuse(re1) + p.stack = p.stack[:n-1] + return true + } + + if n >= 2 { + re1 := p.stack[n-1] + re2 := p.stack[n-2] + if re2.Op == opVerticalBar { + if n >= 3 { + // Now out of reach. + // Clean opportunistically. + cleanAlt(p.stack[n-3]) + } + p.stack[n-2] = re1 + p.stack[n-1] = re2 + return true + } + } + return false +} + +// parseRightParen handles a ) in the input. +func (p *parser) parseRightParen() os.Error { + p.concat() + if p.swapVerticalBar() { + // pop vertical bar + p.stack = p.stack[:len(p.stack)-1] + } + p.alternate() + + n := len(p.stack) + if n < 2 { + return &Error{ErrInternalError, ""} + } + re1 := p.stack[n-1] + re2 := p.stack[n-2] + p.stack = p.stack[:n-2] + if re2.Op != opLeftParen { + return &Error{ErrMissingParen, p.wholeRegexp} + } + if re2.Cap == 0 { + // Just for grouping. + p.push(re1) + } else { + re2.Op = OpCapture + re2.Sub = re2.Sub0[:1] + re2.Sub[0] = re1 + p.push(re2) + } + return nil +} + +// parseEscape parses an escape sequence at the beginning of s +// and returns the rune. +func (p *parser) parseEscape(s string) (r int, rest string, err os.Error) { + t := s[1:] + if t == "" { + return 0, "", &Error{ErrTrailingBackslash, ""} + } + c, t, err := nextRune(t) + if err != nil { + return 0, "", err + } + +Switch: + switch c { + default: + if c < utf8.RuneSelf && !isalnum(c) { + // Escaped non-word characters are always themselves. + // PCRE is not quite so rigorous: it accepts things like + // \q, but we don't. We once rejected \_, but too many + // programs and people insist on using it, so allow \_. + return c, t, nil + } + + // Octal escapes. + case '1', '2', '3', '4', '5', '6', '7': + // Single non-zero digit is a backreference; not supported + if t == "" || t[0] < '0' || t[0] > '7' { + break + } + fallthrough + case '0': + // Consume up to three octal digits; already have one. + r = c - '0' + for i := 1; i < 3; i++ { + if t == "" || t[0] < '0' || t[0] > '7' { + break + } + r = r*8 + int(t[0]) - '0' + t = t[1:] + } + return r, t, nil + + // Hexadecimal escapes. + case 'x': + if t == "" { + break + } + if c, t, err = nextRune(t); err != nil { + return 0, "", err + } + if c == '{' { + // Any number of digits in braces. + // Perl accepts any text at all; it ignores all text + // after the first non-hex digit. We require only hex digits, + // and at least one. + nhex := 0 + r = 0 + for { + if t == "" { + break Switch + } + if c, t, err = nextRune(t); err != nil { + return 0, "", err + } + if c == '}' { + break + } + v := unhex(c) + if v < 0 { + break Switch + } + r = r*16 + v + if r > unicode.MaxRune { + break Switch + } + nhex++ + } + if nhex == 0 { + break Switch + } + return r, t, nil + } + + // Easy case: two hex digits. + x := unhex(c) + if c, t, err = nextRune(t); err != nil { + return 0, "", err + } + y := unhex(c) + if x < 0 || y < 0 { + break + } + return x*16 + y, t, nil + + // C escapes. There is no case 'b', to avoid misparsing + // the Perl word-boundary \b as the C backspace \b + // when in POSIX mode. In Perl, /\b/ means word-boundary + // but /[\b]/ means backspace. We don't support that. + // If you want a backspace, embed a literal backspace + // character or use \x08. + case 'a': + return '\a', t, err + case 'f': + return '\f', t, err + case 'n': + return '\n', t, err + case 'r': + return '\r', t, err + case 't': + return '\t', t, err + case 'v': + return '\v', t, err + } + return 0, "", &Error{ErrInvalidEscape, s[:len(s)-len(t)]} +} + +// parseClassChar parses a character class character at the beginning of s +// and returns it. +func (p *parser) parseClassChar(s, wholeClass string) (r int, rest string, err os.Error) { + if s == "" { + return 0, "", &Error{Code: ErrMissingBracket, Expr: wholeClass} + } + + // Allow regular escape sequences even though + // many need not be escaped in this context. + if s[0] == '\\' { + return p.parseEscape(s) + } + + return nextRune(s) +} + +type charGroup struct { + sign int + class []int +} + +// parsePerlClassEscape parses a leading Perl character class escape like \d +// from the beginning of s. If one is present, it appends the characters to r +// and returns the new slice r and the remainder of the string. +func (p *parser) parsePerlClassEscape(s string, r []int) (out []int, rest string) { + if p.flags&PerlX == 0 || len(s) < 2 || s[0] != '\\' { + return + } + g := perlGroup[s[0:2]] + if g.sign == 0 { + return + } + return p.appendGroup(r, g), s[2:] +} + +// parseNamedClass parses a leading POSIX named character class like [:alnum:] +// from the beginning of s. If one is present, it appends the characters to r +// and returns the new slice r and the remainder of the string. +func (p *parser) parseNamedClass(s string, r []int) (out []int, rest string, err os.Error) { + if len(s) < 2 || s[0] != '[' || s[1] != ':' { + return + } + + i := strings.Index(s[2:], ":]") + if i < 0 { + return + } + i += 2 + name, s := s[0:i+2], s[i+2:] + g := posixGroup[name] + if g.sign == 0 { + return nil, "", &Error{ErrInvalidCharRange, name} + } + return p.appendGroup(r, g), s, nil +} + +func (p *parser) appendGroup(r []int, g charGroup) []int { + if p.flags&FoldCase == 0 { + if g.sign < 0 { + r = appendNegatedClass(r, g.class) + } else { + r = appendClass(r, g.class) + } + } else { + tmp := p.tmpClass[:0] + tmp = appendFoldedClass(tmp, g.class) + p.tmpClass = tmp + tmp = cleanClass(&p.tmpClass) + if g.sign < 0 { + r = appendNegatedClass(r, tmp) + } else { + r = appendClass(r, tmp) + } + } + return r +} + +// unicodeTable returns the unicode.RangeTable identified by name +// and the table of additional fold-equivalent code points. +func unicodeTable(name string) (*unicode.RangeTable, *unicode.RangeTable) { + if t := unicode.Categories[name]; t != nil { + return t, unicode.FoldCategory[name] + } + if t := unicode.Scripts[name]; t != nil { + return t, unicode.FoldScript[name] + } + return nil, nil +} + +// parseUnicodeClass parses a leading Unicode character class like \p{Han} +// from the beginning of s. If one is present, it appends the characters to r +// and returns the new slice r and the remainder of the string. +func (p *parser) parseUnicodeClass(s string, r []int) (out []int, rest string, err os.Error) { + if p.flags&UnicodeGroups == 0 || len(s) < 2 || s[0] != '\\' || s[1] != 'p' && s[1] != 'P' { + return + } + + // Committed to parse or return error. + sign := +1 + if s[1] == 'P' { + sign = -1 + } + t := s[2:] + c, t, err := nextRune(t) + if err != nil { + return + } + var seq, name string + if c != '{' { + // Single-letter name. + seq = s[:len(s)-len(t)] + name = seq[2:] + } else { + // Name is in braces. + end := strings.IndexRune(s, '}') + if end < 0 { + if err = checkUTF8(s); err != nil { + return + } + return nil, "", &Error{ErrInvalidCharRange, s} + } + seq, t = s[:end+1], s[end+1:] + name = s[3:end] + if err = checkUTF8(name); err != nil { + return + } + } + + // Group can have leading negation too. \p{^Han} == \P{Han}, \P{^Han} == \p{Han}. + if name != "" && name[0] == '^' { + sign = -sign + name = name[1:] + } + + tab, fold := unicodeTable(name) + if tab == nil { + return nil, "", &Error{ErrInvalidCharRange, seq} + } + + if p.flags&FoldCase == 0 || fold == nil { + if sign > 0 { + r = appendTable(r, tab) + } else { + r = appendNegatedTable(r, tab) + } + } else { + // Merge and clean tab and fold in a temporary buffer. + // This is necessary for the negative case and just tidy + // for the positive case. + tmp := p.tmpClass[:0] + tmp = appendTable(tmp, tab) + tmp = appendTable(tmp, fold) + p.tmpClass = tmp + tmp = cleanClass(&p.tmpClass) + if sign > 0 { + r = appendClass(r, tmp) + } else { + r = appendNegatedClass(r, tmp) + } + } + return r, t, nil +} + +// parseClass parses a character class at the beginning of s +// and pushes it onto the parse stack. +func (p *parser) parseClass(s string) (rest string, err os.Error) { + t := s[1:] // chop [ + re := p.newRegexp(OpCharClass) + re.Flags = p.flags + re.Rune = re.Rune0[:0] + + sign := +1 + if t != "" && t[0] == '^' { + sign = -1 + t = t[1:] + + // If character class does not match \n, add it here, + // so that negation later will do the right thing. + if p.flags&ClassNL == 0 { + re.Rune = append(re.Rune, '\n', '\n') + } + } + + class := re.Rune + first := true // ] and - are okay as first char in class + for t == "" || t[0] != ']' || first { + // POSIX: - is only okay unescaped as first or last in class. + // Perl: - is okay anywhere. + if t != "" && t[0] == '-' && p.flags&PerlX == 0 && !first && (len(t) == 1 || t[1] != ']') { + _, size := utf8.DecodeRuneInString(t[1:]) + return "", &Error{Code: ErrInvalidCharRange, Expr: t[:1+size]} + } + first = false + + // Look for POSIX [:alnum:] etc. + if len(t) > 2 && t[0] == '[' && t[1] == ':' { + nclass, nt, err := p.parseNamedClass(t, class) + if err != nil { + return "", err + } + if nclass != nil { + class, t = nclass, nt + continue + } + } + + // Look for Unicode character group like \p{Han}. + nclass, nt, err := p.parseUnicodeClass(t, class) + if err != nil { + return "", err + } + if nclass != nil { + class, t = nclass, nt + continue + } + + // Look for Perl character class symbols (extension). + if nclass, nt := p.parsePerlClassEscape(t, class); nclass != nil { + class, t = nclass, nt + continue + } + + // Single character or simple range. + rng := t + var lo, hi int + if lo, t, err = p.parseClassChar(t, s); err != nil { + return "", err + } + hi = lo + // [a-] means (a|-) so check for final ]. + if len(t) >= 2 && t[0] == '-' && t[1] != ']' { + t = t[1:] + if hi, t, err = p.parseClassChar(t, s); err != nil { + return "", err + } + if hi < lo { + rng = rng[:len(rng)-len(t)] + return "", &Error{Code: ErrInvalidCharRange, Expr: rng} + } + } + if p.flags&FoldCase == 0 { + class = appendRange(class, lo, hi) + } else { + class = appendFoldedRange(class, lo, hi) + } + } + t = t[1:] // chop ] + + // Use &re.Rune instead of &class to avoid allocation. + re.Rune = class + class = cleanClass(&re.Rune) + if sign < 0 { + class = negateClass(class) + } + re.Rune = class + p.push(re) + return t, nil +} + +// cleanClass sorts the ranges (pairs of elements of r), +// merges them, and eliminates duplicates. +func cleanClass(rp *[]int) []int { + + // Sort by lo increasing, hi decreasing to break ties. + sort.Sort(ranges{rp}) + + r := *rp + if len(r) < 2 { + return r + } + + // Merge abutting, overlapping. + w := 2 // write index + for i := 2; i < len(r); i += 2 { + lo, hi := r[i], r[i+1] + if lo <= r[w-1]+1 { + // merge with previous range + if hi > r[w-1] { + r[w-1] = hi + } + continue + } + // new disjoint range + r[w] = lo + r[w+1] = hi + w += 2 + } + + return r[:w] +} + +// appendRange returns the result of appending the range lo-hi to the class r. +func appendRange(r []int, lo, hi int) []int { + // Expand last range or next to last range if it overlaps or abuts. + // Checking two ranges helps when appending case-folded + // alphabets, so that one range can be expanding A-Z and the + // other expanding a-z. + n := len(r) + for i := 2; i <= 4; i += 2 { // twice, using i=2, i=4 + if n >= i { + rlo, rhi := r[n-i], r[n-i+1] + if lo <= rhi+1 && rlo <= hi+1 { + if lo < rlo { + r[n-i] = lo + } + if hi > rhi { + r[n-i+1] = hi + } + return r + } + } + } + + return append(r, lo, hi) +} + +const ( + // minimum and maximum runes involved in folding. + // checked during test. + minFold = 0x0041 + maxFold = 0x1044f +) + +// appendFoldedRange returns the result of appending the range lo-hi +// and its case folding-equivalent runes to the class r. +func appendFoldedRange(r []int, lo, hi int) []int { + // Optimizations. + if lo <= minFold && hi >= maxFold { + // Range is full: folding can't add more. + return appendRange(r, lo, hi) + } + if hi < minFold || lo > maxFold { + // Range is outside folding possibilities. + return appendRange(r, lo, hi) + } + if lo < minFold { + // [lo, minFold-1] needs no folding. + r = appendRange(r, lo, minFold-1) + lo = minFold + } + if hi > maxFold { + // [maxFold+1, hi] needs no folding. + r = appendRange(r, maxFold+1, hi) + hi = maxFold + } + + // Brute force. Depend on appendRange to coalesce ranges on the fly. + for c := lo; c <= hi; c++ { + r = appendRange(r, c, c) + f := unicode.SimpleFold(c) + for f != c { + r = appendRange(r, f, f) + f = unicode.SimpleFold(f) + } + } + return r +} + +// appendClass returns the result of appending the class x to the class r. +// It assume x is clean. +func appendClass(r []int, x []int) []int { + for i := 0; i < len(x); i += 2 { + r = appendRange(r, x[i], x[i+1]) + } + return r +} + +// appendFolded returns the result of appending the case folding of the class x to the class r. +func appendFoldedClass(r []int, x []int) []int { + for i := 0; i < len(x); i += 2 { + r = appendFoldedRange(r, x[i], x[i+1]) + } + return r +} + +// appendNegatedClass returns the result of appending the negation of the class x to the class r. +// It assumes x is clean. +func appendNegatedClass(r []int, x []int) []int { + nextLo := 0 + for i := 0; i < len(x); i += 2 { + lo, hi := x[i], x[i+1] + if nextLo <= lo-1 { + r = appendRange(r, nextLo, lo-1) + } + nextLo = hi + 1 + } + if nextLo <= unicode.MaxRune { + r = appendRange(r, nextLo, unicode.MaxRune) + } + return r +} + +// appendTable returns the result of appending x to the class r. +func appendTable(r []int, x *unicode.RangeTable) []int { + for _, xr := range x.R16 { + lo, hi, stride := int(xr.Lo), int(xr.Hi), int(xr.Stride) + if stride == 1 { + r = appendRange(r, lo, hi) + continue + } + for c := lo; c <= hi; c += stride { + r = appendRange(r, c, c) + } + } + for _, xr := range x.R32 { + lo, hi, stride := int(xr.Lo), int(xr.Hi), int(xr.Stride) + if stride == 1 { + r = appendRange(r, lo, hi) + continue + } + for c := lo; c <= hi; c += stride { + r = appendRange(r, c, c) + } + } + return r +} + +// appendNegatedTable returns the result of appending the negation of x to the class r. +func appendNegatedTable(r []int, x *unicode.RangeTable) []int { + nextLo := 0 // lo end of next class to add + for _, xr := range x.R16 { + lo, hi, stride := int(xr.Lo), int(xr.Hi), int(xr.Stride) + if stride == 1 { + if nextLo <= lo-1 { + r = appendRange(r, nextLo, lo-1) + } + nextLo = hi + 1 + continue + } + for c := lo; c <= hi; c += stride { + if nextLo <= c-1 { + r = appendRange(r, nextLo, c-1) + } + nextLo = c + 1 + } + } + for _, xr := range x.R32 { + lo, hi, stride := int(xr.Lo), int(xr.Hi), int(xr.Stride) + if stride == 1 { + if nextLo <= lo-1 { + r = appendRange(r, nextLo, lo-1) + } + nextLo = hi + 1 + continue + } + for c := lo; c <= hi; c += stride { + if nextLo <= c-1 { + r = appendRange(r, nextLo, c-1) + } + nextLo = c + 1 + } + } + if nextLo <= unicode.MaxRune { + r = appendRange(r, nextLo, unicode.MaxRune) + } + return r +} + +// negateClass overwrites r and returns r's negation. +// It assumes the class r is already clean. +func negateClass(r []int) []int { + nextLo := 0 // lo end of next class to add + w := 0 // write index + for i := 0; i < len(r); i += 2 { + lo, hi := r[i], r[i+1] + if nextLo <= lo-1 { + r[w] = nextLo + r[w+1] = lo - 1 + w += 2 + } + nextLo = hi + 1 + } + r = r[:w] + if nextLo <= unicode.MaxRune { + // It's possible for the negation to have one more + // range - this one - than the original class, so use append. + r = append(r, nextLo, unicode.MaxRune) + } + return r +} + +// ranges implements sort.Interface on a []rune. +// The choice of receiver type definition is strange +// but avoids an allocation since we already have +// a *[]int. +type ranges struct { + p *[]int +} + +func (ra ranges) Less(i, j int) bool { + p := *ra.p + i *= 2 + j *= 2 + return p[i] < p[j] || p[i] == p[j] && p[i+1] > p[j+1] +} + +func (ra ranges) Len() int { + return len(*ra.p) / 2 +} + +func (ra ranges) Swap(i, j int) { + p := *ra.p + i *= 2 + j *= 2 + p[i], p[i+1], p[j], p[j+1] = p[j], p[j+1], p[i], p[i+1] +} + +func checkUTF8(s string) os.Error { + for s != "" { + rune, size := utf8.DecodeRuneInString(s) + if rune == utf8.RuneError && size == 1 { + return &Error{Code: ErrInvalidUTF8, Expr: s} + } + s = s[size:] + } + return nil +} + +func nextRune(s string) (c int, t string, err os.Error) { + c, size := utf8.DecodeRuneInString(s) + if c == utf8.RuneError && size == 1 { + return 0, "", &Error{Code: ErrInvalidUTF8, Expr: s} + } + return c, s[size:], nil +} + +func isalnum(c int) bool { + return '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' +} + +func unhex(c int) int { + if '0' <= c && c <= '9' { + return c - '0' + } + if 'a' <= c && c <= 'f' { + return c - 'a' + 10 + } + if 'A' <= c && c <= 'F' { + return c - 'A' + 10 + } + return -1 +} diff --git a/libgo/go/exp/regexp/syntax/parse_test.go b/libgo/go/exp/regexp/syntax/parse_test.go new file mode 100644 index 00000000000..779b9afdeae --- /dev/null +++ b/libgo/go/exp/regexp/syntax/parse_test.go @@ -0,0 +1,350 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package syntax + +import ( + "bytes" + "fmt" + "testing" + "unicode" +) + +var parseTests = []struct { + Regexp string + Dump string +}{ + // Base cases + {`a`, `lit{a}`}, + {`a.`, `cat{lit{a}dot{}}`}, + {`a.b`, `cat{lit{a}dot{}lit{b}}`}, + {`ab`, `str{ab}`}, + {`a.b.c`, `cat{lit{a}dot{}lit{b}dot{}lit{c}}`}, + {`abc`, `str{abc}`}, + {`a|^`, `alt{lit{a}bol{}}`}, + {`a|b`, `cc{0x61-0x62}`}, + {`(a)`, `cap{lit{a}}`}, + {`(a)|b`, `alt{cap{lit{a}}lit{b}}`}, + {`a*`, `star{lit{a}}`}, + {`a+`, `plus{lit{a}}`}, + {`a?`, `que{lit{a}}`}, + {`a{2}`, `rep{2,2 lit{a}}`}, + {`a{2,3}`, `rep{2,3 lit{a}}`}, + {`a{2,}`, `rep{2,-1 lit{a}}`}, + {`a*?`, `nstar{lit{a}}`}, + {`a+?`, `nplus{lit{a}}`}, + {`a??`, `nque{lit{a}}`}, + {`a{2}?`, `nrep{2,2 lit{a}}`}, + {`a{2,3}?`, `nrep{2,3 lit{a}}`}, + {`a{2,}?`, `nrep{2,-1 lit{a}}`}, + {``, `emp{}`}, + {`|`, `emp{}`}, // alt{emp{}emp{}} but got factored + {`|x|`, `alt{emp{}lit{x}emp{}}`}, + {`.`, `dot{}`}, + {`^`, `bol{}`}, + {`$`, `eol{}`}, + {`\|`, `lit{|}`}, + {`\(`, `lit{(}`}, + {`\)`, `lit{)}`}, + {`\*`, `lit{*}`}, + {`\+`, `lit{+}`}, + {`\?`, `lit{?}`}, + {`{`, `lit{{}`}, + {`}`, `lit{}}`}, + {`\.`, `lit{.}`}, + {`\^`, `lit{^}`}, + {`\$`, `lit{$}`}, + {`\\`, `lit{\}`}, + {`[ace]`, `cc{0x61 0x63 0x65}`}, + {`[abc]`, `cc{0x61-0x63}`}, + {`[a-z]`, `cc{0x61-0x7a}`}, + {`[a]`, `lit{a}`}, + {`\-`, `lit{-}`}, + {`-`, `lit{-}`}, + {`\_`, `lit{_}`}, + {`abc`, `str{abc}`}, + {`abc|def`, `alt{str{abc}str{def}}`}, + {`abc|def|ghi`, `alt{str{abc}str{def}str{ghi}}`}, + + // Posix and Perl extensions + {`[[:lower:]]`, `cc{0x61-0x7a}`}, + {`[a-z]`, `cc{0x61-0x7a}`}, + {`[^[:lower:]]`, `cc{0x0-0x60 0x7b-0x10ffff}`}, + {`[[:^lower:]]`, `cc{0x0-0x60 0x7b-0x10ffff}`}, + {`(?i)[[:lower:]]`, `cc{0x41-0x5a 0x61-0x7a 0x17f 0x212a}`}, + {`(?i)[a-z]`, `cc{0x41-0x5a 0x61-0x7a 0x17f 0x212a}`}, + {`(?i)[^[:lower:]]`, `cc{0x0-0x40 0x5b-0x60 0x7b-0x17e 0x180-0x2129 0x212b-0x10ffff}`}, + {`(?i)[[:^lower:]]`, `cc{0x0-0x40 0x5b-0x60 0x7b-0x17e 0x180-0x2129 0x212b-0x10ffff}`}, + {`\d`, `cc{0x30-0x39}`}, + {`\D`, `cc{0x0-0x2f 0x3a-0x10ffff}`}, + {`\s`, `cc{0x9-0xa 0xc-0xd 0x20}`}, + {`\S`, `cc{0x0-0x8 0xb 0xe-0x1f 0x21-0x10ffff}`}, + {`\w`, `cc{0x30-0x39 0x41-0x5a 0x5f 0x61-0x7a}`}, + {`\W`, `cc{0x0-0x2f 0x3a-0x40 0x5b-0x5e 0x60 0x7b-0x10ffff}`}, + {`(?i)\w`, `cc{0x30-0x39 0x41-0x5a 0x5f 0x61-0x7a 0x17f 0x212a}`}, + {`(?i)\W`, `cc{0x0-0x2f 0x3a-0x40 0x5b-0x5e 0x60 0x7b-0x17e 0x180-0x2129 0x212b-0x10ffff}`}, + {`[^\\]`, `cc{0x0-0x5b 0x5d-0x10ffff}`}, + // { `\C`, `byte{}` }, // probably never + + // Unicode, negatives, and a double negative. + {`\p{Braille}`, `cc{0x2800-0x28ff}`}, + {`\P{Braille}`, `cc{0x0-0x27ff 0x2900-0x10ffff}`}, + {`\p{^Braille}`, `cc{0x0-0x27ff 0x2900-0x10ffff}`}, + {`\P{^Braille}`, `cc{0x2800-0x28ff}`}, + {`\pZ`, `cc{0x20 0xa0 0x1680 0x180e 0x2000-0x200a 0x2028-0x2029 0x202f 0x205f 0x3000}`}, + {`[\p{Braille}]`, `cc{0x2800-0x28ff}`}, + {`[\P{Braille}]`, `cc{0x0-0x27ff 0x2900-0x10ffff}`}, + {`[\p{^Braille}]`, `cc{0x0-0x27ff 0x2900-0x10ffff}`}, + {`[\P{^Braille}]`, `cc{0x2800-0x28ff}`}, + {`[\pZ]`, `cc{0x20 0xa0 0x1680 0x180e 0x2000-0x200a 0x2028-0x2029 0x202f 0x205f 0x3000}`}, + {`\p{Lu}`, mkCharClass(unicode.IsUpper)}, + {`[\p{Lu}]`, mkCharClass(unicode.IsUpper)}, + {`(?i)[\p{Lu}]`, mkCharClass(isUpperFold)}, + + // Hex, octal. + {`[\012-\234]\141`, `cat{cc{0xa-0x9c}lit{a}}`}, + {`[\x{41}-\x7a]\x61`, `cat{cc{0x41-0x7a}lit{a}}`}, + + // More interesting regular expressions. + {`a{,2}`, `str{a{,2}}`}, + {`\.\^\$\\`, `str{.^$\}`}, + {`[a-zABC]`, `cc{0x41-0x43 0x61-0x7a}`}, + {`[^a]`, `cc{0x0-0x60 0x62-0x10ffff}`}, + {`[α-ε☺]`, `cc{0x3b1-0x3b5 0x263a}`}, // utf-8 + {`a*{`, `cat{star{lit{a}}lit{{}}`}, + + // Test precedences + {`(?:ab)*`, `star{str{ab}}`}, + {`(ab)*`, `star{cap{str{ab}}}`}, + {`ab|cd`, `alt{str{ab}str{cd}}`}, + {`a(b|c)d`, `cat{lit{a}cap{cc{0x62-0x63}}lit{d}}`}, + + // Test flattening. + {`(?:a)`, `lit{a}`}, + {`(?:ab)(?:cd)`, `str{abcd}`}, + {`(?:a+b+)(?:c+d+)`, `cat{plus{lit{a}}plus{lit{b}}plus{lit{c}}plus{lit{d}}}`}, + {`(?:a+|b+)|(?:c+|d+)`, `alt{plus{lit{a}}plus{lit{b}}plus{lit{c}}plus{lit{d}}}`}, + {`(?:a|b)|(?:c|d)`, `cc{0x61-0x64}`}, + {`a|.`, `dot{}`}, + {`.|a`, `dot{}`}, + {`(?:[abc]|A|Z|hello|world)`, `alt{cc{0x41 0x5a 0x61-0x63}str{hello}str{world}}`}, + {`(?:[abc]|A|Z)`, `cc{0x41 0x5a 0x61-0x63}`}, + + // Test Perl quoted literals + {`\Q+|*?{[\E`, `str{+|*?{[}`}, + {`\Q+\E+`, `plus{lit{+}}`}, + {`\Q\\E`, `lit{\}`}, + {`\Q\\\E`, `str{\\}`}, + + // Test Perl \A and \z + {`(?m)^`, `bol{}`}, + {`(?m)$`, `eol{}`}, + {`(?-m)^`, `bot{}`}, + {`(?-m)$`, `eot{}`}, + {`(?m)\A`, `bot{}`}, + {`(?m)\z`, `eot{\z}`}, + {`(?-m)\A`, `bot{}`}, + {`(?-m)\z`, `eot{\z}`}, + + // Test named captures + {`(?P<name>a)`, `cap{name:lit{a}}`}, + + // Case-folded literals + {`[Aa]`, `litfold{A}`}, + {`[\x{100}\x{101}]`, `litfold{Ā}`}, + {`[Δδ]`, `litfold{Δ}`}, + + // Strings + {`abcde`, `str{abcde}`}, + {`[Aa][Bb]cd`, `cat{strfold{AB}str{cd}}`}, + + // Factoring. + {`abc|abd|aef|bcx|bcy`, `alt{cat{lit{a}alt{cat{lit{b}cc{0x63-0x64}}str{ef}}}cat{str{bc}cc{0x78-0x79}}}`}, + {`ax+y|ax+z|ay+w`, `cat{lit{a}alt{cat{plus{lit{x}}cc{0x79-0x7a}}cat{plus{lit{y}}lit{w}}}}`}, +} + +const testFlags = MatchNL | PerlX | UnicodeGroups + +// Test Parse -> Dump. +func TestParseDump(t *testing.T) { + for _, tt := range parseTests { + re, err := Parse(tt.Regexp, testFlags) + if err != nil { + t.Errorf("Parse(%#q): %v", tt.Regexp, err) + continue + } + d := dump(re) + if d != tt.Dump { + t.Errorf("Parse(%#q).Dump() = %#q want %#q", tt.Regexp, d, tt.Dump) + } + } +} + +// dump prints a string representation of the regexp showing +// the structure explicitly. +func dump(re *Regexp) string { + var b bytes.Buffer + dumpRegexp(&b, re) + return b.String() +} + +var opNames = []string{ + OpNoMatch: "no", + OpEmptyMatch: "emp", + OpLiteral: "lit", + OpCharClass: "cc", + OpAnyCharNotNL: "dnl", + OpAnyChar: "dot", + OpBeginLine: "bol", + OpEndLine: "eol", + OpBeginText: "bot", + OpEndText: "eot", + OpWordBoundary: "wb", + OpNoWordBoundary: "nwb", + OpCapture: "cap", + OpStar: "star", + OpPlus: "plus", + OpQuest: "que", + OpRepeat: "rep", + OpConcat: "cat", + OpAlternate: "alt", +} + +// dumpRegexp writes an encoding of the syntax tree for the regexp re to b. +// It is used during testing to distinguish between parses that might print +// the same using re's String method. +func dumpRegexp(b *bytes.Buffer, re *Regexp) { + if int(re.Op) >= len(opNames) || opNames[re.Op] == "" { + fmt.Fprintf(b, "op%d", re.Op) + } else { + switch re.Op { + default: + b.WriteString(opNames[re.Op]) + case OpStar, OpPlus, OpQuest, OpRepeat: + if re.Flags&NonGreedy != 0 { + b.WriteByte('n') + } + b.WriteString(opNames[re.Op]) + case OpLiteral: + if len(re.Rune) > 1 { + b.WriteString("str") + } else { + b.WriteString("lit") + } + if re.Flags&FoldCase != 0 { + for _, r := range re.Rune { + if unicode.SimpleFold(r) != r { + b.WriteString("fold") + break + } + } + } + } + } + b.WriteByte('{') + switch re.Op { + case OpEndText: + if re.Flags&WasDollar == 0 { + b.WriteString(`\z`) + } + case OpLiteral: + for _, r := range re.Rune { + b.WriteRune(r) + } + case OpConcat, OpAlternate: + for _, sub := range re.Sub { + dumpRegexp(b, sub) + } + case OpStar, OpPlus, OpQuest: + dumpRegexp(b, re.Sub[0]) + case OpRepeat: + fmt.Fprintf(b, "%d,%d ", re.Min, re.Max) + dumpRegexp(b, re.Sub[0]) + case OpCapture: + if re.Name != "" { + b.WriteString(re.Name) + b.WriteByte(':') + } + dumpRegexp(b, re.Sub[0]) + case OpCharClass: + sep := "" + for i := 0; i < len(re.Rune); i += 2 { + b.WriteString(sep) + sep = " " + lo, hi := re.Rune[i], re.Rune[i+1] + if lo == hi { + fmt.Fprintf(b, "%#x", lo) + } else { + fmt.Fprintf(b, "%#x-%#x", lo, hi) + } + } + } + b.WriteByte('}') +} + +func mkCharClass(f func(int) bool) string { + re := &Regexp{Op: OpCharClass} + lo := -1 + for i := 0; i <= unicode.MaxRune; i++ { + if f(i) { + if lo < 0 { + lo = i + } + } else { + if lo >= 0 { + re.Rune = append(re.Rune, lo, i-1) + lo = -1 + } + } + } + if lo >= 0 { + re.Rune = append(re.Rune, lo, unicode.MaxRune) + } + return dump(re) +} + +func isUpperFold(rune int) bool { + if unicode.IsUpper(rune) { + return true + } + c := unicode.SimpleFold(rune) + for c != rune { + if unicode.IsUpper(c) { + return true + } + c = unicode.SimpleFold(c) + } + return false +} + +func TestFoldConstants(t *testing.T) { + last := -1 + for i := 0; i <= unicode.MaxRune; i++ { + if unicode.SimpleFold(i) == i { + continue + } + if last == -1 && minFold != i { + t.Errorf("minFold=%#U should be %#U", minFold, i) + } + last = i + } + if maxFold != last { + t.Errorf("maxFold=%#U should be %#U", maxFold, last) + } +} + +func TestAppendRangeCollapse(t *testing.T) { + // AppendRange should collapse each of the new ranges + // into the earlier ones (it looks back two ranges), so that + // the slice never grows very large. + // Note that we are not calling cleanClass. + var r []int + for i := 'A'; i <= 'Z'; i++ { + r = appendRange(r, i, i) + r = appendRange(r, i+'a'-'A', i+'a'-'A') + } + if string(r) != "AZaz" { + t.Errorf("appendRange interlaced A-Z a-z = %s, want AZaz", string(r)) + } +} diff --git a/libgo/go/exp/regexp/syntax/perl_groups.go b/libgo/go/exp/regexp/syntax/perl_groups.go new file mode 100644 index 00000000000..05b392c40d8 --- /dev/null +++ b/libgo/go/exp/regexp/syntax/perl_groups.go @@ -0,0 +1,130 @@ +// GENERATED BY make_perl_groups.pl; DO NOT EDIT. +// make_perl_groups.pl >perl_groups.go + +package syntax + +var code1 = []int{ /* \d */ + 0x30, 0x39, +} + +var code2 = []int{ /* \s */ + 0x9, 0xa, + 0xc, 0xd, + 0x20, 0x20, +} + +var code3 = []int{ /* \w */ + 0x30, 0x39, + 0x41, 0x5a, + 0x5f, 0x5f, + 0x61, 0x7a, +} + +var perlGroup = map[string]charGroup{ + `\d`: {+1, code1}, + `\D`: {-1, code1}, + `\s`: {+1, code2}, + `\S`: {-1, code2}, + `\w`: {+1, code3}, + `\W`: {-1, code3}, +} +var code4 = []int{ /* [:alnum:] */ + 0x30, 0x39, + 0x41, 0x5a, + 0x61, 0x7a, +} + +var code5 = []int{ /* [:alpha:] */ + 0x41, 0x5a, + 0x61, 0x7a, +} + +var code6 = []int{ /* [:ascii:] */ + 0x0, 0x7f, +} + +var code7 = []int{ /* [:blank:] */ + 0x9, 0x9, + 0x20, 0x20, +} + +var code8 = []int{ /* [:cntrl:] */ + 0x0, 0x1f, + 0x7f, 0x7f, +} + +var code9 = []int{ /* [:digit:] */ + 0x30, 0x39, +} + +var code10 = []int{ /* [:graph:] */ + 0x21, 0x7e, +} + +var code11 = []int{ /* [:lower:] */ + 0x61, 0x7a, +} + +var code12 = []int{ /* [:print:] */ + 0x20, 0x7e, +} + +var code13 = []int{ /* [:punct:] */ + 0x21, 0x2f, + 0x3a, 0x40, + 0x5b, 0x60, + 0x7b, 0x7e, +} + +var code14 = []int{ /* [:space:] */ + 0x9, 0xd, + 0x20, 0x20, +} + +var code15 = []int{ /* [:upper:] */ + 0x41, 0x5a, +} + +var code16 = []int{ /* [:word:] */ + 0x30, 0x39, + 0x41, 0x5a, + 0x5f, 0x5f, + 0x61, 0x7a, +} + +var code17 = []int{ /* [:xdigit:] */ + 0x30, 0x39, + 0x41, 0x46, + 0x61, 0x66, +} + +var posixGroup = map[string]charGroup{ + `[:alnum:]`: {+1, code4}, + `[:^alnum:]`: {-1, code4}, + `[:alpha:]`: {+1, code5}, + `[:^alpha:]`: {-1, code5}, + `[:ascii:]`: {+1, code6}, + `[:^ascii:]`: {-1, code6}, + `[:blank:]`: {+1, code7}, + `[:^blank:]`: {-1, code7}, + `[:cntrl:]`: {+1, code8}, + `[:^cntrl:]`: {-1, code8}, + `[:digit:]`: {+1, code9}, + `[:^digit:]`: {-1, code9}, + `[:graph:]`: {+1, code10}, + `[:^graph:]`: {-1, code10}, + `[:lower:]`: {+1, code11}, + `[:^lower:]`: {-1, code11}, + `[:print:]`: {+1, code12}, + `[:^print:]`: {-1, code12}, + `[:punct:]`: {+1, code13}, + `[:^punct:]`: {-1, code13}, + `[:space:]`: {+1, code14}, + `[:^space:]`: {-1, code14}, + `[:upper:]`: {+1, code15}, + `[:^upper:]`: {-1, code15}, + `[:word:]`: {+1, code16}, + `[:^word:]`: {-1, code16}, + `[:xdigit:]`: {+1, code17}, + `[:^xdigit:]`: {-1, code17}, +} diff --git a/libgo/go/exp/regexp/syntax/prog.go b/libgo/go/exp/regexp/syntax/prog.go new file mode 100644 index 00000000000..bf85b720d02 --- /dev/null +++ b/libgo/go/exp/regexp/syntax/prog.go @@ -0,0 +1,237 @@ +package syntax + +import ( + "bytes" + "strconv" +) + +// Compiled program. +// May not belong in this package, but convenient for now. + +// A Prog is a compiled regular expression program. +type Prog struct { + Inst []Inst + Start int // index of start instruction + NumCap int // number of InstCapture insts in re +} + +// An InstOp is an instruction opcode. +type InstOp uint8 + +const ( + InstAlt InstOp = iota + InstAltMatch + InstCapture + InstEmptyWidth + InstMatch + InstFail + InstNop + InstRune +) + +// An EmptyOp specifies a kind or mixture of zero-width assertions. +type EmptyOp uint8 + +const ( + EmptyBeginLine EmptyOp = 1 << iota + EmptyEndLine + EmptyBeginText + EmptyEndText + EmptyWordBoundary + EmptyNoWordBoundary +) + +// An Inst is a single instruction in a regular expression program. +type Inst struct { + Op InstOp + Out uint32 // all but InstMatch, InstFail + Arg uint32 // InstAlt, InstAltMatch, InstCapture, InstEmptyWidth + Rune []int +} + +func (p *Prog) String() string { + var b bytes.Buffer + dumpProg(&b, p) + return b.String() +} + +// skipNop follows any no-op or capturing instructions +// and returns the resulting pc. +func (p *Prog) skipNop(pc uint32) *Inst { + i := &p.Inst[pc] + for i.Op == InstNop || i.Op == InstCapture { + pc = i.Out + i = &p.Inst[pc] + } + return i +} + +// Prefix returns a literal string that all matches for the +// regexp must start with. Complete is true if the prefix +// is the entire match. +func (p *Prog) Prefix() (prefix string, complete bool) { + i := p.skipNop(uint32(p.Start)) + + // Avoid allocation of buffer if prefix is empty. + if i.Op != InstRune || len(i.Rune) != 1 { + return "", i.Op == InstMatch + } + + // Have prefix; gather characters. + var buf bytes.Buffer + for i.Op == InstRune && len(i.Rune) == 1 { + buf.WriteRune(i.Rune[0]) + i = p.skipNop(i.Out) + } + return buf.String(), i.Op == InstMatch +} + +// StartCond returns the leading empty-width conditions that must +// be true in any match. It returns ^EmptyOp(0) if no matches are possible. +func (p *Prog) StartCond() EmptyOp { + var flag EmptyOp + pc := uint32(p.Start) + i := &p.Inst[pc] +Loop: + for { + switch i.Op { + case InstEmptyWidth: + flag |= EmptyOp(i.Arg) + case InstFail: + return ^EmptyOp(0) + case InstCapture, InstNop: + // skip + default: + break Loop + } + pc = i.Out + i = &p.Inst[pc] + } + return flag +} + +// MatchRune returns true if the instruction matches (and consumes) r. +// It should only be called when i.Op == InstRune. +func (i *Inst) MatchRune(r int) bool { + rune := i.Rune + + // Special case: single-rune slice is from literal string, not char class. + // TODO: Case folding. + if len(rune) == 1 { + return r == rune[0] + } + + // Peek at the first few pairs. + // Should handle ASCII well. + for j := 0; j < len(rune) && j <= 8; j += 2 { + if r < rune[j] { + return false + } + if r <= rune[j+1] { + return true + } + } + + // Otherwise binary search. + lo := 0 + hi := len(rune) / 2 + for lo < hi { + m := lo + (hi-lo)/2 + if c := rune[2*m]; c <= r { + if r <= rune[2*m+1] { + return true + } + lo = m + 1 + } else { + hi = m + } + } + return false +} + +// As per re2's Prog::IsWordChar. Determines whether rune is an ASCII word char. +// Since we act on runes, it would be easy to support Unicode here. +func wordRune(rune int) bool { + return rune == '_' || + ('A' <= rune && rune <= 'Z') || + ('a' <= rune && rune <= 'z') || + ('0' <= rune && rune <= '9') +} + +// MatchEmptyWidth returns true if the instruction matches +// an empty string between the runes before and after. +// It should only be called when i.Op == InstEmptyWidth. +func (i *Inst) MatchEmptyWidth(before int, after int) bool { + switch EmptyOp(i.Arg) { + case EmptyBeginLine: + return before == '\n' || before == -1 + case EmptyEndLine: + return after == '\n' || after == -1 + case EmptyBeginText: + return before == -1 + case EmptyEndText: + return after == -1 + case EmptyWordBoundary: + return wordRune(before) != wordRune(after) + case EmptyNoWordBoundary: + return wordRune(before) == wordRune(after) + } + panic("unknown empty width arg") +} + +func (i *Inst) String() string { + var b bytes.Buffer + dumpInst(&b, i) + return b.String() +} + +func bw(b *bytes.Buffer, args ...string) { + for _, s := range args { + b.WriteString(s) + } +} + +func dumpProg(b *bytes.Buffer, p *Prog) { + for j := range p.Inst { + i := &p.Inst[j] + pc := strconv.Itoa(j) + if len(pc) < 3 { + b.WriteString(" "[len(pc):]) + } + if j == p.Start { + pc += "*" + } + bw(b, pc, "\t") + dumpInst(b, i) + bw(b, "\n") + } +} + +func u32(i uint32) string { + return strconv.Uitoa64(uint64(i)) +} + +func dumpInst(b *bytes.Buffer, i *Inst) { + switch i.Op { + case InstAlt: + bw(b, "alt -> ", u32(i.Out), ", ", u32(i.Arg)) + case InstAltMatch: + bw(b, "altmatch -> ", u32(i.Out), ", ", u32(i.Arg)) + case InstCapture: + bw(b, "cap ", u32(i.Arg), " -> ", u32(i.Out)) + case InstEmptyWidth: + bw(b, "empty ", u32(i.Arg), " -> ", u32(i.Out)) + case InstMatch: + bw(b, "match") + case InstFail: + bw(b, "fail") + case InstNop: + bw(b, "nop -> ", u32(i.Out)) + case InstRune: + if i.Rune == nil { + // shouldn't happen + bw(b, "rune <nil>") + } + bw(b, "rune ", strconv.QuoteToASCII(string(i.Rune)), " -> ", u32(i.Out)) + } +} diff --git a/libgo/go/exp/regexp/syntax/prog_test.go b/libgo/go/exp/regexp/syntax/prog_test.go new file mode 100644 index 00000000000..7be4281c27f --- /dev/null +++ b/libgo/go/exp/regexp/syntax/prog_test.go @@ -0,0 +1,91 @@ +package syntax + +import ( + "testing" +) + +var compileTests = []struct { + Regexp string + Prog string +}{ + {"a", ` 0 fail + 1* rune "a" -> 2 + 2 match +`}, + {"[A-M][n-z]", ` 0 fail + 1* rune "AM" -> 2 + 2 rune "nz" -> 3 + 3 match +`}, + {"", ` 0 fail + 1* nop -> 2 + 2 match +`}, + {"a?", ` 0 fail + 1 rune "a" -> 3 + 2* alt -> 1, 3 + 3 match +`}, + {"a??", ` 0 fail + 1 rune "a" -> 3 + 2* alt -> 3, 1 + 3 match +`}, + {"a+", ` 0 fail + 1* rune "a" -> 2 + 2 alt -> 1, 3 + 3 match +`}, + {"a+?", ` 0 fail + 1* rune "a" -> 2 + 2 alt -> 3, 1 + 3 match +`}, + {"a*", ` 0 fail + 1 rune "a" -> 2 + 2* alt -> 1, 3 + 3 match +`}, + {"a*?", ` 0 fail + 1 rune "a" -> 2 + 2* alt -> 3, 1 + 3 match +`}, + {"a+b+", ` 0 fail + 1* rune "a" -> 2 + 2 alt -> 1, 3 + 3 rune "b" -> 4 + 4 alt -> 3, 5 + 5 match +`}, + {"(a+)(b+)", ` 0 fail + 1* cap 2 -> 2 + 2 rune "a" -> 3 + 3 alt -> 2, 4 + 4 cap 3 -> 5 + 5 cap 4 -> 6 + 6 rune "b" -> 7 + 7 alt -> 6, 8 + 8 cap 5 -> 9 + 9 match +`}, + {"a+|b+", ` 0 fail + 1 rune "a" -> 2 + 2 alt -> 1, 6 + 3 rune "b" -> 4 + 4 alt -> 3, 6 + 5* alt -> 1, 3 + 6 match +`}, +} + +func TestCompile(t *testing.T) { + for _, tt := range compileTests { + re, _ := Parse(tt.Regexp, Perl) + p, _ := Compile(re) + s := p.String() + if s != tt.Prog { + t.Errorf("compiled %#q:\n--- have\n%s---\n--- want\n%s---", tt.Regexp, s, tt.Prog) + } + } +} diff --git a/libgo/go/exp/regexp/syntax/regexp.go b/libgo/go/exp/regexp/syntax/regexp.go new file mode 100644 index 00000000000..00a4addefc4 --- /dev/null +++ b/libgo/go/exp/regexp/syntax/regexp.go @@ -0,0 +1,284 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package syntax parses regular expressions into syntax trees. +// WORK IN PROGRESS. +package syntax + +// Note to implementers: +// In this package, re is always a *Regexp and r is always a rune. + +import ( + "bytes" + "strconv" + "strings" + "unicode" +) + +// A Regexp is a node in a regular expression syntax tree. +type Regexp struct { + Op Op // operator + Flags Flags + Sub []*Regexp // subexpressions, if any + Sub0 [1]*Regexp // storage for short Sub + Rune []int // matched runes, for OpLiteral, OpCharClass + Rune0 [2]int // storage for short Rune + Min, Max int // min, max for OpRepeat + Cap int // capturing index, for OpCapture + Name string // capturing name, for OpCapture +} + +// An Op is a single regular expression operator. +type Op uint8 + +// Operators are listed in precedence order, tightest binding to weakest. +// Character class operators are listed simplest to most complex +// (OpLiteral, OpCharClass, OpAnyCharNotNL, OpAnyChar). + +const ( + OpNoMatch Op = 1 + iota // matches no strings + OpEmptyMatch // matches empty string + OpLiteral // matches Runes sequence + OpCharClass // matches Runes interpreted as range pair list + OpAnyCharNotNL // matches any character + OpAnyChar // matches any character + OpBeginLine // matches empty string at beginning of line + OpEndLine // matches empty string at end of line + OpBeginText // matches empty string at beginning of text + OpEndText // matches empty string at end of text + OpWordBoundary // matches word boundary `\b` + OpNoWordBoundary // matches word non-boundary `\B` + OpCapture // capturing subexpression with index Cap, optional name Name + OpStar // matches Sub[0] zero or more times + OpPlus // matches Sub[0] one or more times + OpQuest // matches Sub[0] zero or one times + OpRepeat // matches Sub[0] at least Min times, at most Max (Max == -1 is no limit) + OpConcat // matches concatenation of Subs + OpAlternate // matches alternation of Subs +) + +const opPseudo Op = 128 // where pseudo-ops start + +// Equal returns true if x and y have identical structure. +func (x *Regexp) Equal(y *Regexp) bool { + if x == nil || y == nil { + return x == y + } + if x.Op != y.Op { + return false + } + switch x.Op { + case OpEndText: + // The parse flags remember whether this is \z or \Z. + if x.Flags&WasDollar != y.Flags&WasDollar { + return false + } + + case OpLiteral, OpCharClass: + if len(x.Rune) != len(y.Rune) { + return false + } + for i, r := range x.Rune { + if r != y.Rune[i] { + return false + } + } + + case OpAlternate, OpConcat: + if len(x.Sub) != len(y.Sub) { + return false + } + for i, sub := range x.Sub { + if !sub.Equal(y.Sub[i]) { + return false + } + } + + case OpStar, OpPlus, OpQuest: + if x.Flags&NonGreedy != y.Flags&NonGreedy || !x.Sub[0].Equal(y.Sub[0]) { + return false + } + + case OpRepeat: + if x.Flags&NonGreedy != y.Flags&NonGreedy || x.Min != y.Min || x.Max != y.Max || !x.Sub[0].Equal(y.Sub[0]) { + return false + } + + case OpCapture: + if x.Cap != y.Cap || x.Name != y.Name || !x.Sub[0].Equal(y.Sub[0]) { + return false + } + } + return true +} + +// writeRegexp writes the Perl syntax for the regular expression re to b. +func writeRegexp(b *bytes.Buffer, re *Regexp) { + switch re.Op { + default: + b.WriteString("<invalid op" + strconv.Itoa(int(re.Op)) + ">") + case OpNoMatch: + b.WriteString(`[^\x00-\x{10FFFF}]`) + case OpEmptyMatch: + b.WriteString(`(?:)`) + case OpLiteral: + if re.Flags&FoldCase != 0 { + b.WriteString(`(?i:`) + } + for _, r := range re.Rune { + escape(b, r, false) + } + if re.Flags&FoldCase != 0 { + b.WriteString(`)`) + } + case OpCharClass: + if len(re.Rune)%2 != 0 { + b.WriteString(`[invalid char class]`) + break + } + b.WriteRune('[') + if len(re.Rune) == 0 { + b.WriteString(`^\x00-\x{10FFFF}`) + } else if re.Rune[0] == 0 && re.Rune[len(re.Rune)-1] == unicode.MaxRune { + // Contains 0 and MaxRune. Probably a negated class. + // Print the gaps. + b.WriteRune('^') + for i := 1; i < len(re.Rune)-1; i += 2 { + lo, hi := re.Rune[i]+1, re.Rune[i+1]-1 + escape(b, lo, lo == '-') + if lo != hi { + b.WriteRune('-') + escape(b, hi, hi == '-') + } + } + } else { + for i := 0; i < len(re.Rune); i += 2 { + lo, hi := re.Rune[i], re.Rune[i+1] + escape(b, lo, lo == '-') + if lo != hi { + b.WriteRune('-') + escape(b, hi, hi == '-') + } + } + } + b.WriteRune(']') + case OpAnyCharNotNL: + b.WriteString(`[^\n]`) + case OpAnyChar: + b.WriteRune('.') + case OpBeginLine: + b.WriteRune('^') + case OpEndLine: + b.WriteRune('$') + case OpBeginText: + b.WriteString(`\A`) + case OpEndText: + b.WriteString(`\z`) + case OpWordBoundary: + b.WriteString(`\b`) + case OpNoWordBoundary: + b.WriteString(`\B`) + case OpCapture: + if re.Name != "" { + b.WriteString(`(?P<`) + b.WriteString(re.Name) + b.WriteRune('>') + } else { + b.WriteRune('(') + } + if re.Sub[0].Op != OpEmptyMatch { + writeRegexp(b, re.Sub[0]) + } + b.WriteRune(')') + case OpStar, OpPlus, OpQuest, OpRepeat: + if sub := re.Sub[0]; sub.Op > OpCapture { + b.WriteString(`(?:`) + writeRegexp(b, sub) + b.WriteString(`)`) + } else { + writeRegexp(b, sub) + } + switch re.Op { + case OpStar: + b.WriteRune('*') + case OpPlus: + b.WriteRune('+') + case OpQuest: + b.WriteRune('?') + case OpRepeat: + b.WriteRune('{') + b.WriteString(strconv.Itoa(re.Min)) + if re.Max != re.Min { + b.WriteRune(',') + if re.Max >= 0 { + b.WriteString(strconv.Itoa(re.Max)) + } + } + b.WriteRune('}') + } + case OpConcat: + for _, sub := range re.Sub { + if sub.Op == OpAlternate { + b.WriteString(`(?:`) + writeRegexp(b, sub) + b.WriteString(`)`) + } else { + writeRegexp(b, sub) + } + } + case OpAlternate: + for i, sub := range re.Sub { + if i > 0 { + b.WriteRune('|') + } + writeRegexp(b, sub) + } + } +} + +func (re *Regexp) String() string { + var b bytes.Buffer + writeRegexp(&b, re) + return b.String() +} + +const meta = `\.+*?()|[]{}^$` + +func escape(b *bytes.Buffer, r int, force bool) { + if unicode.IsPrint(r) { + if strings.IndexRune(meta, r) >= 0 || force { + b.WriteRune('\\') + } + b.WriteRune(r) + return + } + + switch r { + case '\a': + b.WriteString(`\a`) + case '\f': + b.WriteString(`\f`) + case '\n': + b.WriteString(`\n`) + case '\r': + b.WriteString(`\r`) + case '\t': + b.WriteString(`\t`) + case '\v': + b.WriteString(`\v`) + default: + if r < 0x100 { + b.WriteString(`\x`) + s := strconv.Itob(r, 16) + if len(s) == 1 { + b.WriteRune('0') + } + b.WriteString(s) + break + } + b.WriteString(`\x{`) + b.WriteString(strconv.Itob(r, 16)) + b.WriteString(`}`) + } +} diff --git a/libgo/go/exp/regexp/syntax/simplify.go b/libgo/go/exp/regexp/syntax/simplify.go new file mode 100644 index 00000000000..72390417bbe --- /dev/null +++ b/libgo/go/exp/regexp/syntax/simplify.go @@ -0,0 +1,151 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package syntax + +// Simplify returns a regexp equivalent to re but without counted repetitions +// and with various other simplifications, such as rewriting /(?:a+)+/ to /a+/. +// The resulting regexp will execute correctly but its string representation +// will not produce the same parse tree, because capturing parentheses +// may have been duplicated or removed. For example, the simplified form +// for /(x){1,2}/ is /(x)(x)?/ but both parentheses capture as $1. +// The returned regexp may share structure with or be the original. +func (re *Regexp) Simplify() *Regexp { + if re == nil { + return nil + } + switch re.Op { + case OpCapture, OpConcat, OpAlternate: + // Simplify children, building new Regexp if children change. + nre := re + for i, sub := range re.Sub { + nsub := sub.Simplify() + if nre == re && nsub != sub { + // Start a copy. + nre = new(Regexp) + *nre = *re + nre.Rune = nil + nre.Sub = append(nre.Sub0[:0], re.Sub[:i]...) + } + if nre != re { + nre.Sub = append(nre.Sub, nsub) + } + } + return nre + + case OpStar, OpPlus, OpQuest: + sub := re.Sub[0].Simplify() + return simplify1(re.Op, re.Flags, sub, re) + + case OpRepeat: + // Special special case: x{0} matches the empty string + // and doesn't even need to consider x. + if re.Min == 0 && re.Max == 0 { + return &Regexp{Op: OpEmptyMatch} + } + + // The fun begins. + sub := re.Sub[0].Simplify() + + // x{n,} means at least n matches of x. + if re.Max == -1 { + // Special case: x{0,} is x*. + if re.Min == 0 { + return simplify1(OpStar, re.Flags, sub, nil) + } + + // Special case: x{1,} is x+. + if re.Min == 1 { + return simplify1(OpPlus, re.Flags, sub, nil) + } + + // General case: x{4,} is xxxx+. + nre := &Regexp{Op: OpConcat} + nre.Sub = nre.Sub0[:0] + for i := 0; i < re.Min-1; i++ { + nre.Sub = append(nre.Sub, sub) + } + nre.Sub = append(nre.Sub, simplify1(OpPlus, re.Flags, sub, nil)) + return nre + } + + // Special case x{0} handled above. + + // Special case: x{1} is just x. + if re.Min == 1 && re.Max == 1 { + return sub + } + + // General case: x{n,m} means n copies of x and m copies of x? + // The machine will do less work if we nest the final m copies, + // so that x{2,5} = xx(x(x(x)?)?)? + + // Build leading prefix: xx. + var prefix *Regexp + if re.Min > 0 { + prefix = &Regexp{Op: OpConcat} + prefix.Sub = prefix.Sub0[:0] + for i := 0; i < re.Min; i++ { + prefix.Sub = append(prefix.Sub, sub) + } + } + + // Build and attach suffix: (x(x(x)?)?)? + if re.Max > re.Min { + suffix := simplify1(OpQuest, re.Flags, sub, nil) + for i := re.Min + 1; i < re.Max; i++ { + nre2 := &Regexp{Op: OpConcat} + nre2.Sub = append(nre2.Sub0[:0], sub, suffix) + suffix = simplify1(OpQuest, re.Flags, nre2, nil) + } + if prefix == nil { + return suffix + } + prefix.Sub = append(prefix.Sub, suffix) + } + if prefix != nil { + return prefix + } + + // Some degenerate case like min > max or min < max < 0. + // Handle as impossible match. + return &Regexp{Op: OpNoMatch} + } + + return re +} + +// simplify1 implements Simplify for the unary OpStar, +// OpPlus, and OpQuest operators. It returns the simple regexp +// equivalent to +// +// Regexp{Op: op, Flags: flags, Sub: {sub}} +// +// under the assumption that sub is already simple, and +// without first allocating that structure. If the regexp +// to be returned turns out to be equivalent to re, simplify1 +// returns re instead. +// +// simplify1 is factored out of Simplify because the implementation +// for other operators generates these unary expressions. +// Letting them call simplify1 makes sure the expressions they +// generate are simple. +func simplify1(op Op, flags Flags, sub, re *Regexp) *Regexp { + // Special case: repeat the empty string as much as + // you want, but it's still the empty string. + if sub.Op == OpEmptyMatch { + return sub + } + // The operators are idempotent if the flags match. + if op == sub.Op && flags&NonGreedy == sub.Flags&NonGreedy { + return sub + } + if re != nil && re.Op == op && re.Flags&NonGreedy == flags&NonGreedy && sub == re.Sub[0] { + return re + } + + re = &Regexp{Op: op, Flags: flags} + re.Sub = append(re.Sub0[:0], sub) + return re +} diff --git a/libgo/go/exp/regexp/syntax/simplify_test.go b/libgo/go/exp/regexp/syntax/simplify_test.go new file mode 100644 index 00000000000..c8cec21831a --- /dev/null +++ b/libgo/go/exp/regexp/syntax/simplify_test.go @@ -0,0 +1,151 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package syntax + +import "testing" + +var simplifyTests = []struct { + Regexp string + Simple string +}{ + // Already-simple constructs + {`a`, `a`}, + {`ab`, `ab`}, + {`a|b`, `[a-b]`}, + {`ab|cd`, `ab|cd`}, + {`(ab)*`, `(ab)*`}, + {`(ab)+`, `(ab)+`}, + {`(ab)?`, `(ab)?`}, + {`.`, `.`}, + {`^`, `^`}, + {`$`, `$`}, + {`[ac]`, `[ac]`}, + {`[^ac]`, `[^ac]`}, + + // Posix character classes + {`[[:alnum:]]`, `[0-9A-Za-z]`}, + {`[[:alpha:]]`, `[A-Za-z]`}, + {`[[:blank:]]`, `[\t ]`}, + {`[[:cntrl:]]`, `[\x00-\x1f\x7f]`}, + {`[[:digit:]]`, `[0-9]`}, + {`[[:graph:]]`, `[!-~]`}, + {`[[:lower:]]`, `[a-z]`}, + {`[[:print:]]`, `[ -~]`}, + {`[[:punct:]]`, "[!-/:-@\\[-`\\{-~]"}, + {`[[:space:]]`, `[\t-\r ]`}, + {`[[:upper:]]`, `[A-Z]`}, + {`[[:xdigit:]]`, `[0-9A-Fa-f]`}, + + // Perl character classes + {`\d`, `[0-9]`}, + {`\s`, `[\t-\n\f-\r ]`}, + {`\w`, `[0-9A-Z_a-z]`}, + {`\D`, `[^0-9]`}, + {`\S`, `[^\t-\n\f-\r ]`}, + {`\W`, `[^0-9A-Z_a-z]`}, + {`[\d]`, `[0-9]`}, + {`[\s]`, `[\t-\n\f-\r ]`}, + {`[\w]`, `[0-9A-Z_a-z]`}, + {`[\D]`, `[^0-9]`}, + {`[\S]`, `[^\t-\n\f-\r ]`}, + {`[\W]`, `[^0-9A-Z_a-z]`}, + + // Posix repetitions + {`a{1}`, `a`}, + {`a{2}`, `aa`}, + {`a{5}`, `aaaaa`}, + {`a{0,1}`, `a?`}, + // The next three are illegible because Simplify inserts (?:) + // parens instead of () parens to avoid creating extra + // captured subexpressions. The comments show a version with fewer parens. + {`(a){0,2}`, `(?:(a)(a)?)?`}, // (aa?)? + {`(a){0,4}`, `(?:(a)(?:(a)(?:(a)(a)?)?)?)?`}, // (a(a(aa?)?)?)? + {`(a){2,6}`, `(a)(a)(?:(a)(?:(a)(?:(a)(a)?)?)?)?`}, // aa(a(a(aa?)?)?)? + {`a{0,2}`, `(?:aa?)?`}, // (aa?)? + {`a{0,4}`, `(?:a(?:a(?:aa?)?)?)?`}, // (a(a(aa?)?)?)? + {`a{2,6}`, `aa(?:a(?:a(?:aa?)?)?)?`}, // aa(a(a(aa?)?)?)? + {`a{0,}`, `a*`}, + {`a{1,}`, `a+`}, + {`a{2,}`, `aa+`}, + {`a{5,}`, `aaaaa+`}, + + // Test that operators simplify their arguments. + {`(?:a{1,}){1,}`, `a+`}, + {`(a{1,}b{1,})`, `(a+b+)`}, + {`a{1,}|b{1,}`, `a+|b+`}, + {`(?:a{1,})*`, `(?:a+)*`}, + {`(?:a{1,})+`, `a+`}, + {`(?:a{1,})?`, `(?:a+)?`}, + {``, `(?:)`}, + {`a{0}`, `(?:)`}, + + // Character class simplification + {`[ab]`, `[a-b]`}, + {`[a-za-za-z]`, `[a-z]`}, + {`[A-Za-zA-Za-z]`, `[A-Za-z]`}, + {`[ABCDEFGH]`, `[A-H]`}, + {`[AB-CD-EF-GH]`, `[A-H]`}, + {`[W-ZP-XE-R]`, `[E-Z]`}, + {`[a-ee-gg-m]`, `[a-m]`}, + {`[a-ea-ha-m]`, `[a-m]`}, + {`[a-ma-ha-e]`, `[a-m]`}, + {`[a-zA-Z0-9 -~]`, `[ -~]`}, + + // Empty character classes + {`[^[:cntrl:][:^cntrl:]]`, `[^\x00-\x{10FFFF}]`}, + + // Full character classes + {`[[:cntrl:][:^cntrl:]]`, `.`}, + + // Unicode case folding. + {`(?i)A`, `(?i:A)`}, + {`(?i)a`, `(?i:a)`}, + {`(?i)[A]`, `(?i:A)`}, + {`(?i)[a]`, `(?i:A)`}, + {`(?i)K`, `(?i:K)`}, + {`(?i)k`, `(?i:k)`}, + {`(?i)\x{212a}`, "(?i:\u212A)"}, + {`(?i)[K]`, "[Kk\u212A]"}, + {`(?i)[k]`, "[Kk\u212A]"}, + {`(?i)[\x{212a}]`, "[Kk\u212A]"}, + {`(?i)[a-z]`, "[A-Za-z\u017F\u212A]"}, + {`(?i)[\x00-\x{FFFD}]`, "[\\x00-\uFFFD]"}, + {`(?i)[\x00-\x{10FFFF}]`, `.`}, + + // Empty string as a regular expression. + // The empty string must be preserved inside parens in order + // to make submatches work right, so these tests are less + // interesting than they might otherwise be. String inserts + // explicit (?:) in place of non-parenthesized empty strings, + // to make them easier to spot for other parsers. + {`(a|b|)`, `([a-b]|(?:))`}, + {`(|)`, `()`}, + {`a()`, `a()`}, + {`(()|())`, `(()|())`}, + {`(a|)`, `(a|(?:))`}, + {`ab()cd()`, `ab()cd()`}, + {`()`, `()`}, + {`()*`, `()*`}, + {`()+`, `()+`}, + {`()?`, `()?`}, + {`(){0}`, `(?:)`}, + {`(){1}`, `()`}, + {`(){1,}`, `()+`}, + {`(){0,2}`, `(?:()()?)?`}, +} + +func TestSimplify(t *testing.T) { + for _, tt := range simplifyTests { + re, err := Parse(tt.Regexp, MatchNL|Perl&^OneLine) + if err != nil { + t.Errorf("Parse(%#q) = error %v", tt.Regexp, err) + continue + } + s := re.Simplify().String() + if s != tt.Simple { + t.Errorf("Simplify(%#q) = %#q, want %#q", tt.Regexp, s, tt.Simple) + } + } +} diff --git a/libgo/go/exp/template/html/context.go b/libgo/go/exp/template/html/context.go new file mode 100644 index 00000000000..41100688343 --- /dev/null +++ b/libgo/go/exp/template/html/context.go @@ -0,0 +1,98 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package html + +import ( + "fmt" +) + +// context describes the state an HTML parser must be in when it reaches the +// portion of HTML produced by evaluating a particular template node. +// +// The zero value of type context is the start context for a template that +// produces an HTML fragment as defined at +// http://www.w3.org/TR/html5/the-end.html#parsing-html-fragments +// where the context element is null. +type context struct { + state state + delim delim +} + +func (c context) String() string { + return fmt.Sprintf("context{state: %s, delim: %s", c.state, c.delim) +} + +// eq is true if the two contexts are identical field-wise. +func (c context) eq(d context) bool { + return c.state == d.state && c.delim == d.delim +} + +// state describes a high-level HTML parser state. +// +// It bounds the top of the element stack, and by extension the HTML +// insertion mode, but also contains state that does not correspond to +// anything in the HTML5 parsing algorithm because a single token +// production in the HTML grammar may contain embedded actions in a template. +// For instance, the quoted HTML attribute produced by +// <div title="Hello {{.World}}"> +// is a single token in HTML's grammar but in a template spans several nodes. +type state uint8 + +const ( + // statePCDATA is parsed character data. An HTML parser is in + // this state when its parse position is outside an HTML tag, + // directive, comment, and special element body. + statePCDATA state = iota + // stateTag occurs before an HTML attribute or the end of a tag. + stateTag + // stateURI occurs inside an HTML attribute whose content is a URI. + stateURI + // stateError is an infectious error state outside any valid + // HTML/CSS/JS construct. + stateError +) + +var stateNames = [...]string{ + statePCDATA: "statePCDATA", + stateTag: "stateTag", + stateURI: "stateURI", + stateError: "stateError", +} + +func (s state) String() string { + if uint(s) < uint(len(stateNames)) { + return stateNames[s] + } + return fmt.Sprintf("illegal state %d", uint(s)) +} + +// delim is the delimiter that will end the current HTML attribute. +type delim uint8 + +const ( + // delimNone occurs outside any attribute. + delimNone delim = iota + // delimDoubleQuote occurs when a double quote (") closes the attribute. + delimDoubleQuote + // delimSingleQuote occurs when a single quote (') closes the attribute. + delimSingleQuote + // delimSpaceOrTagEnd occurs when a space or right angle bracket (>) + // closes the attribute. + delimSpaceOrTagEnd +) + +var delimNames = [...]string{ + delimNone: "delimNone", + delimDoubleQuote: "delimDoubleQuote", + delimSingleQuote: "delimSingleQuote", + delimSpaceOrTagEnd: "delimSpaceOrTagEnd", +} + +func (d delim) String() string { + if uint(d) < uint(len(delimNames)) { + return delimNames[d] + } + return fmt.Sprintf("illegal delim %d", uint(d)) +} diff --git a/libgo/go/exp/template/html/escape.go b/libgo/go/exp/template/html/escape.go new file mode 100644 index 00000000000..e0e87b98d04 --- /dev/null +++ b/libgo/go/exp/template/html/escape.go @@ -0,0 +1,105 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package html is a specialization of exp/template that automates the +// construction of safe HTML output. +// At the moment, the escaping is naive. All dynamic content is assumed to be +// plain text interpolated in an HTML PCDATA context. +package html + +import ( + "template" + "template/parse" +) + +// Escape rewrites each action in the template to guarantee the output is +// HTML-escaped. +func Escape(t *template.Template) { + // If the parser shares trees based on common-subexpression + // joining then we will need to avoid multiply escaping the same action. + escapeListNode(t.Tree.Root) +} + +// escapeNode dispatches to escape<NodeType> helpers by type. +func escapeNode(node parse.Node) { + switch n := node.(type) { + case *parse.ListNode: + escapeListNode(n) + case *parse.TextNode: + // Nothing to do. + case *parse.ActionNode: + escapeActionNode(n) + case *parse.IfNode: + escapeIfNode(n) + case *parse.RangeNode: + escapeRangeNode(n) + case *parse.TemplateNode: + // Nothing to do. + case *parse.WithNode: + escapeWithNode(n) + default: + panic("handling for " + node.String() + " not implemented") + // TODO: Handle other inner node types. + } +} + +// escapeListNode recursively escapes its input's children. +func escapeListNode(node *parse.ListNode) { + if node == nil { + return + } + children := node.Nodes + for _, child := range children { + escapeNode(child) + } +} + +// escapeActionNode adds a pipeline call to the end that escapes the result +// of the expression before it is interpolated into the template output. +func escapeActionNode(node *parse.ActionNode) { + pipe := node.Pipe + + cmds := pipe.Cmds + nCmds := len(cmds) + + // If it already has an escaping command, do not interfere. + if nCmds != 0 { + if lastCmd := cmds[nCmds-1]; len(lastCmd.Args) != 0 { + // TODO: Recognize url and js as escaping functions once + // we have enough context to know whether additional + // escaping is necessary. + if arg, ok := lastCmd.Args[0].(*parse.IdentifierNode); ok && arg.Ident == "html" { + return + } + } + } + + htmlEscapeCommand := parse.CommandNode{ + NodeType: parse.NodeCommand, + Args: []parse.Node{parse.NewIdentifier("html")}, + } + + node.Pipe.Cmds = append(node.Pipe.Cmds, &htmlEscapeCommand) +} + +// escapeIfNode recursively escapes the if and then clauses but leaves the +// condition unchanged. +func escapeIfNode(node *parse.IfNode) { + escapeListNode(node.List) + escapeListNode(node.ElseList) +} + +// escapeRangeNode recursively escapes the loop body and else clause but +// leaves the series unchanged. +func escapeRangeNode(node *parse.RangeNode) { + escapeListNode(node.List) + escapeListNode(node.ElseList) +} + +// escapeWithNode recursively escapes the scope body and else clause but +// leaves the pipeline unchanged. +func escapeWithNode(node *parse.WithNode) { + escapeListNode(node.List) + escapeListNode(node.ElseList) +} diff --git a/libgo/go/exp/template/html/escape_test.go b/libgo/go/exp/template/html/escape_test.go new file mode 100644 index 00000000000..345a752a896 --- /dev/null +++ b/libgo/go/exp/template/html/escape_test.go @@ -0,0 +1,75 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package html + +import ( + "bytes" + "template" + "testing" +) + +type data struct { + F, T bool + C, G, H string + A, E []string +} + +var testData = data{ + F: false, + T: true, + C: "<Cincinatti>", + G: "<Goodbye>", + H: "<Hello>", + A: []string{"<a>", "<b>"}, + E: []string{}, +} + +type testCase struct { + name string + input string + output string +} + +var testCases = []testCase{ + {"if", "{{if .T}}Hello{{end}}, {{.C}}!", "Hello, <Cincinatti>!"}, + {"else", "{{if .F}}{{.H}}{{else}}{{.G}}{{end}}!", "<Goodbye>!"}, + {"overescaping", "Hello, {{.C | html}}!", "Hello, <Cincinatti>!"}, + {"assignment", "{{if $x := .H}}{{$x}}{{end}}", "<Hello>"}, + {"withBody", "{{with .H}}{{.}}{{end}}", "<Hello>"}, + {"withElse", "{{with .E}}{{.}}{{else}}{{.H}}{{end}}", "<Hello>"}, + {"rangeBody", "{{range .A}}{{.}}{{end}}", "<a><b>"}, + {"rangeElse", "{{range .E}}{{.}}{{else}}{{.H}}{{end}}", "<Hello>"}, + {"nonStringValue", "{{.T}}", "true"}, + {"constant", `<a href="{{"'str'"}}">`, `<a href="'str'">`}, +} + +func TestAutoesc(t *testing.T) { + for _, testCase := range testCases { + name := testCase.name + tmpl := template.New(name) + tmpl, err := tmpl.Parse(testCase.input) + if err != nil { + t.Errorf("%s: failed to parse template: %s", name, err) + continue + } + + Escape(tmpl) + + buffer := new(bytes.Buffer) + + err = tmpl.Execute(buffer, testData) + if err != nil { + t.Errorf("%s: template execution failed: %s", name, err) + continue + } + + output := testCase.output + actual := buffer.String() + if output != actual { + t.Errorf("%s: escaped output: %q != %q", + name, output, actual) + } + } +} diff --git a/libgo/go/exp/wingui/winapi.go b/libgo/go/exp/wingui/winapi.go index c96f452999f..31b57a2cc86 100644 --- a/libgo/go/exp/wingui/winapi.go +++ b/libgo/go/exp/wingui/winapi.go @@ -5,26 +5,9 @@ package main import ( - "syscall" "unsafe" ) -func loadDll(fname string) uint32 { - h, e := syscall.LoadLibrary(fname) - if e != 0 { - abortf("LoadLibrary(%s) failed with err=%d.\n", fname, e) - } - return h -} - -func getSysProcAddr(m uint32, pname string) uintptr { - p, e := syscall.GetProcAddress(m, pname) - if e != 0 { - abortf("GetProcAddress(%s) failed with err=%d.\n", pname, e) - } - return uintptr(p) -} - type Wndclassex struct { Size uint32 Style uint32 @@ -96,7 +79,7 @@ const ( // Some button control styles BS_DEFPUSHBUTTON = 1 - // Some colour constants + // Some color constants COLOR_WINDOW = 5 COLOR_BTNFACE = 15 @@ -108,13 +91,13 @@ const ( ) var ( - // Some globaly known cusrors + // Some globally known cursors IDC_ARROW = MakeIntResource(32512) IDC_IBEAM = MakeIntResource(32513) IDC_WAIT = MakeIntResource(32514) IDC_CROSS = MakeIntResource(32515) - // Some globaly known icons + // Some globally known icons IDI_APPLICATION = MakeIntResource(32512) IDI_HAND = MakeIntResource(32513) IDI_QUESTION = MakeIntResource(32514) diff --git a/libgo/go/exp/wingui/zwinapi.go b/libgo/go/exp/wingui/zwinapi.go index 6ae6330a1fa..4c009dd69bc 100644 --- a/libgo/go/exp/wingui/zwinapi.go +++ b/libgo/go/exp/wingui/zwinapi.go @@ -7,29 +7,29 @@ import "unsafe" import "syscall" var ( - modkernel32 = loadDll("kernel32.dll") - moduser32 = loadDll("user32.dll") - - procGetModuleHandleW = getSysProcAddr(modkernel32, "GetModuleHandleW") - procRegisterClassExW = getSysProcAddr(moduser32, "RegisterClassExW") - procCreateWindowExW = getSysProcAddr(moduser32, "CreateWindowExW") - procDefWindowProcW = getSysProcAddr(moduser32, "DefWindowProcW") - procDestroyWindow = getSysProcAddr(moduser32, "DestroyWindow") - procPostQuitMessage = getSysProcAddr(moduser32, "PostQuitMessage") - procShowWindow = getSysProcAddr(moduser32, "ShowWindow") - procUpdateWindow = getSysProcAddr(moduser32, "UpdateWindow") - procGetMessageW = getSysProcAddr(moduser32, "GetMessageW") - procTranslateMessage = getSysProcAddr(moduser32, "TranslateMessage") - procDispatchMessageW = getSysProcAddr(moduser32, "DispatchMessageW") - procLoadIconW = getSysProcAddr(moduser32, "LoadIconW") - procLoadCursorW = getSysProcAddr(moduser32, "LoadCursorW") - procSetCursor = getSysProcAddr(moduser32, "SetCursor") - procSendMessageW = getSysProcAddr(moduser32, "SendMessageW") - procPostMessageW = getSysProcAddr(moduser32, "PostMessageW") + modkernel32 = syscall.NewLazyDLL("kernel32.dll") + moduser32 = syscall.NewLazyDLL("user32.dll") + + procGetModuleHandleW = modkernel32.NewProc("GetModuleHandleW") + procRegisterClassExW = moduser32.NewProc("RegisterClassExW") + procCreateWindowExW = moduser32.NewProc("CreateWindowExW") + procDefWindowProcW = moduser32.NewProc("DefWindowProcW") + procDestroyWindow = moduser32.NewProc("DestroyWindow") + procPostQuitMessage = moduser32.NewProc("PostQuitMessage") + procShowWindow = moduser32.NewProc("ShowWindow") + procUpdateWindow = moduser32.NewProc("UpdateWindow") + procGetMessageW = moduser32.NewProc("GetMessageW") + procTranslateMessage = moduser32.NewProc("TranslateMessage") + procDispatchMessageW = moduser32.NewProc("DispatchMessageW") + procLoadIconW = moduser32.NewProc("LoadIconW") + procLoadCursorW = moduser32.NewProc("LoadCursorW") + procSetCursor = moduser32.NewProc("SetCursor") + procSendMessageW = moduser32.NewProc("SendMessageW") + procPostMessageW = moduser32.NewProc("PostMessageW") ) func GetModuleHandle(modname *uint16) (handle uint32, errno int) { - r0, _, e1 := syscall.Syscall(procGetModuleHandleW, 1, uintptr(unsafe.Pointer(modname)), 0, 0) + r0, _, e1 := syscall.Syscall(procGetModuleHandleW.Addr(), 1, uintptr(unsafe.Pointer(modname)), 0, 0) handle = uint32(r0) if handle == 0 { if e1 != 0 { @@ -44,7 +44,7 @@ func GetModuleHandle(modname *uint16) (handle uint32, errno int) { } func RegisterClassEx(wndclass *Wndclassex) (atom uint16, errno int) { - r0, _, e1 := syscall.Syscall(procRegisterClassExW, 1, uintptr(unsafe.Pointer(wndclass)), 0, 0) + r0, _, e1 := syscall.Syscall(procRegisterClassExW.Addr(), 1, uintptr(unsafe.Pointer(wndclass)), 0, 0) atom = uint16(r0) if atom == 0 { if e1 != 0 { @@ -59,7 +59,7 @@ func RegisterClassEx(wndclass *Wndclassex) (atom uint16, errno int) { } func CreateWindowEx(exstyle uint32, classname *uint16, windowname *uint16, style uint32, x int32, y int32, width int32, height int32, wndparent uint32, menu uint32, instance uint32, param uintptr) (hwnd uint32, errno int) { - r0, _, e1 := syscall.Syscall12(procCreateWindowExW, 12, uintptr(exstyle), uintptr(unsafe.Pointer(classname)), uintptr(unsafe.Pointer(windowname)), uintptr(style), uintptr(x), uintptr(y), uintptr(width), uintptr(height), uintptr(wndparent), uintptr(menu), uintptr(instance), uintptr(param)) + r0, _, e1 := syscall.Syscall12(procCreateWindowExW.Addr(), 12, uintptr(exstyle), uintptr(unsafe.Pointer(classname)), uintptr(unsafe.Pointer(windowname)), uintptr(style), uintptr(x), uintptr(y), uintptr(width), uintptr(height), uintptr(wndparent), uintptr(menu), uintptr(instance), uintptr(param)) hwnd = uint32(r0) if hwnd == 0 { if e1 != 0 { @@ -74,13 +74,13 @@ func CreateWindowEx(exstyle uint32, classname *uint16, windowname *uint16, style } func DefWindowProc(hwnd uint32, msg uint32, wparam int32, lparam int32) (lresult int32) { - r0, _, _ := syscall.Syscall6(procDefWindowProcW, 4, uintptr(hwnd), uintptr(msg), uintptr(wparam), uintptr(lparam), 0, 0) + r0, _, _ := syscall.Syscall6(procDefWindowProcW.Addr(), 4, uintptr(hwnd), uintptr(msg), uintptr(wparam), uintptr(lparam), 0, 0) lresult = int32(r0) return } func DestroyWindow(hwnd uint32) (errno int) { - r1, _, e1 := syscall.Syscall(procDestroyWindow, 1, uintptr(hwnd), 0, 0) + r1, _, e1 := syscall.Syscall(procDestroyWindow.Addr(), 1, uintptr(hwnd), 0, 0) if int(r1) == 0 { if e1 != 0 { errno = int(e1) @@ -94,18 +94,18 @@ func DestroyWindow(hwnd uint32) (errno int) { } func PostQuitMessage(exitcode int32) { - syscall.Syscall(procPostQuitMessage, 1, uintptr(exitcode), 0, 0) + syscall.Syscall(procPostQuitMessage.Addr(), 1, uintptr(exitcode), 0, 0) return } func ShowWindow(hwnd uint32, cmdshow int32) (wasvisible bool) { - r0, _, _ := syscall.Syscall(procShowWindow, 2, uintptr(hwnd), uintptr(cmdshow), 0) + r0, _, _ := syscall.Syscall(procShowWindow.Addr(), 2, uintptr(hwnd), uintptr(cmdshow), 0) wasvisible = bool(r0 != 0) return } func UpdateWindow(hwnd uint32) (errno int) { - r1, _, e1 := syscall.Syscall(procUpdateWindow, 1, uintptr(hwnd), 0, 0) + r1, _, e1 := syscall.Syscall(procUpdateWindow.Addr(), 1, uintptr(hwnd), 0, 0) if int(r1) == 0 { if e1 != 0 { errno = int(e1) @@ -119,7 +119,7 @@ func UpdateWindow(hwnd uint32) (errno int) { } func GetMessage(msg *Msg, hwnd uint32, MsgFilterMin uint32, MsgFilterMax uint32) (ret int32, errno int) { - r0, _, e1 := syscall.Syscall6(procGetMessageW, 4, uintptr(unsafe.Pointer(msg)), uintptr(hwnd), uintptr(MsgFilterMin), uintptr(MsgFilterMax), 0, 0) + r0, _, e1 := syscall.Syscall6(procGetMessageW.Addr(), 4, uintptr(unsafe.Pointer(msg)), uintptr(hwnd), uintptr(MsgFilterMin), uintptr(MsgFilterMax), 0, 0) ret = int32(r0) if ret == -1 { if e1 != 0 { @@ -134,19 +134,19 @@ func GetMessage(msg *Msg, hwnd uint32, MsgFilterMin uint32, MsgFilterMax uint32) } func TranslateMessage(msg *Msg) (done bool) { - r0, _, _ := syscall.Syscall(procTranslateMessage, 1, uintptr(unsafe.Pointer(msg)), 0, 0) + r0, _, _ := syscall.Syscall(procTranslateMessage.Addr(), 1, uintptr(unsafe.Pointer(msg)), 0, 0) done = bool(r0 != 0) return } func DispatchMessage(msg *Msg) (ret int32) { - r0, _, _ := syscall.Syscall(procDispatchMessageW, 1, uintptr(unsafe.Pointer(msg)), 0, 0) + r0, _, _ := syscall.Syscall(procDispatchMessageW.Addr(), 1, uintptr(unsafe.Pointer(msg)), 0, 0) ret = int32(r0) return } func LoadIcon(instance uint32, iconname *uint16) (icon uint32, errno int) { - r0, _, e1 := syscall.Syscall(procLoadIconW, 2, uintptr(instance), uintptr(unsafe.Pointer(iconname)), 0) + r0, _, e1 := syscall.Syscall(procLoadIconW.Addr(), 2, uintptr(instance), uintptr(unsafe.Pointer(iconname)), 0) icon = uint32(r0) if icon == 0 { if e1 != 0 { @@ -161,7 +161,7 @@ func LoadIcon(instance uint32, iconname *uint16) (icon uint32, errno int) { } func LoadCursor(instance uint32, cursorname *uint16) (cursor uint32, errno int) { - r0, _, e1 := syscall.Syscall(procLoadCursorW, 2, uintptr(instance), uintptr(unsafe.Pointer(cursorname)), 0) + r0, _, e1 := syscall.Syscall(procLoadCursorW.Addr(), 2, uintptr(instance), uintptr(unsafe.Pointer(cursorname)), 0) cursor = uint32(r0) if cursor == 0 { if e1 != 0 { @@ -176,7 +176,7 @@ func LoadCursor(instance uint32, cursorname *uint16) (cursor uint32, errno int) } func SetCursor(cursor uint32) (precursor uint32, errno int) { - r0, _, e1 := syscall.Syscall(procSetCursor, 1, uintptr(cursor), 0, 0) + r0, _, e1 := syscall.Syscall(procSetCursor.Addr(), 1, uintptr(cursor), 0, 0) precursor = uint32(r0) if precursor == 0 { if e1 != 0 { @@ -191,13 +191,13 @@ func SetCursor(cursor uint32) (precursor uint32, errno int) { } func SendMessage(hwnd uint32, msg uint32, wparam int32, lparam int32) (lresult int32) { - r0, _, _ := syscall.Syscall6(procSendMessageW, 4, uintptr(hwnd), uintptr(msg), uintptr(wparam), uintptr(lparam), 0, 0) + r0, _, _ := syscall.Syscall6(procSendMessageW.Addr(), 4, uintptr(hwnd), uintptr(msg), uintptr(wparam), uintptr(lparam), 0, 0) lresult = int32(r0) return } func PostMessage(hwnd uint32, msg uint32, wparam int32, lparam int32) (errno int) { - r1, _, e1 := syscall.Syscall6(procPostMessageW, 4, uintptr(hwnd), uintptr(msg), uintptr(wparam), uintptr(lparam), 0, 0) + r1, _, e1 := syscall.Syscall6(procPostMessageW.Addr(), 4, uintptr(hwnd), uintptr(msg), uintptr(wparam), uintptr(lparam), 0, 0) if int(r1) == 0 { if e1 != 0 { errno = int(e1) |