split asmsub and romsub declarations

This commit is contained in:
Irmen de Jong 2020-03-10 23:09:31 +01:00
parent 96d8a7f0d7
commit 98a638a2f3
8 changed files with 1585 additions and 1502 deletions

View File

@ -41,25 +41,25 @@ c64flt {
; note: for subtraction and division, the left operand is in fac2, the right operand in fac1. ; note: for subtraction and division, the left operand is in fac2, the right operand in fac1.
; checked functions below: ; checked functions below:
asmsub MOVFM (uword mflpt @ AY) clobbers(A,Y) = $bba2 ; load mflpt value from memory in A/Y into fac1 romsub $bba2 = MOVFM(uword mflpt @ AY) clobbers(A,Y) ; load mflpt value from memory in A/Y into fac1
asmsub FREADMEM () clobbers(A,Y) = $bba6 ; load mflpt value from memory in $22/$23 into fac1 romsub $bba6 = FREADMEM() clobbers(A,Y) ; load mflpt value from memory in $22/$23 into fac1
asmsub CONUPK (uword mflpt @ AY) clobbers(A,Y) = $ba8c ; load mflpt value from memory in A/Y into fac2 romsub $ba8c = CONUPK(uword mflpt @ AY) clobbers(A,Y) ; load mflpt value from memory in A/Y into fac2
asmsub FAREADMEM () clobbers(A,Y) = $ba90 ; load mflpt value from memory in $22/$23 into fac2 romsub $ba90 = FAREADMEM() clobbers(A,Y) ; load mflpt value from memory in $22/$23 into fac2
asmsub MOVFA () clobbers(A,X) = $bbfc ; copy fac2 to fac1 romsub $bbfc = MOVFA() clobbers(A,X) ; copy fac2 to fac1
asmsub MOVAF () clobbers(A,X) = $bc0c ; copy fac1 to fac2 (rounded) romsub $bc0c = MOVAF() clobbers(A,X) ; copy fac1 to fac2 (rounded)
asmsub MOVEF () clobbers(A,X) = $bc0f ; copy fac1 to fac2 romsub $bc0f = MOVEF() clobbers(A,X) ; copy fac1 to fac2
asmsub MOVMF (uword mflpt @ XY) clobbers(A,Y) = $bbd4 ; store fac1 to memory X/Y as 5-byte mflpt romsub $bbd4 = MOVMF(uword mflpt @ XY) clobbers(A,Y) ; store fac1 to memory X/Y as 5-byte mflpt
; fac1-> signed word in Y/A (might throw ILLEGAL QUANTITY) ; fac1-> signed word in Y/A (might throw ILLEGAL QUANTITY)
; (tip: use c64flt.FTOSWRDAY to get A/Y output; lo/hi switched to normal little endian order) ; (tip: use c64flt.FTOSWRDAY to get A/Y output; lo/hi switched to normal little endian order)
asmsub FTOSWORDYA () clobbers(X) -> ubyte @ Y, ubyte @ A = $b1aa ; note: calls AYINT. romsub $b1aa = FTOSWORDYA() clobbers(X) -> ubyte @ Y, ubyte @ A ; note: calls AYINT.
; fac1 -> unsigned word in Y/A (might throw ILLEGAL QUANTITY) (result also in $14/15) ; fac1 -> unsigned word in Y/A (might throw ILLEGAL QUANTITY) (result also in $14/15)
; (tip: use c64flt.GETADRAY to get A/Y output; lo/hi switched to normal little endian order) ; (tip: use c64flt.GETADRAY to get A/Y output; lo/hi switched to normal little endian order)
asmsub GETADR () clobbers(X) -> ubyte @ Y, ubyte @ A = $b7f7 romsub $b7f7 = GETADR() clobbers(X) -> ubyte @ Y, ubyte @ A
asmsub QINT () clobbers(A,X,Y) = $bc9b ; fac1 -> 4-byte signed integer in 98-101 ($62-$65), with the MSB FIRST. romsub $bc9b = QINT() clobbers(A,X,Y) ; fac1 -> 4-byte signed integer in 98-101 ($62-$65), with the MSB FIRST.
asmsub AYINT () clobbers(A,X,Y) = $b1bf ; fac1-> signed word in 100-101 ($64-$65) MSB FIRST. (might throw ILLEGAL QUANTITY) romsub $b1bf = AYINT() clobbers(A,X,Y) ; fac1-> signed word in 100-101 ($64-$65) MSB FIRST. (might throw ILLEGAL QUANTITY)
; GIVAYF: signed word in Y/A (note different lsb/msb order) -> float in fac1 ; GIVAYF: signed word in Y/A (note different lsb/msb order) -> float in fac1
; (tip: use c64flt.GIVAYFAY to use A/Y input; lo/hi switched to normal order) ; (tip: use c64flt.GIVAYFAY to use A/Y input; lo/hi switched to normal order)
@ -67,50 +67,49 @@ asmsub AYINT () clobbers(A,X,Y) = $b1bf ; fac1-> signed word in 100-101 ($64
; there is also c64flt.FREADS32 that reads from 98-101 ($62-$65) MSB FIRST ; there is also c64flt.FREADS32 that reads from 98-101 ($62-$65) MSB FIRST
; there is also c64flt.FREADUS32 that reads from 98-101 ($62-$65) MSB FIRST ; there is also c64flt.FREADUS32 that reads from 98-101 ($62-$65) MSB FIRST
; there is also c64flt.FREADS24AXY that reads signed int24 into fac1 from A/X/Y (lo/mid/hi bytes) ; there is also c64flt.FREADS24AXY that reads signed int24 into fac1 from A/X/Y (lo/mid/hi bytes)
asmsub GIVAYF (ubyte lo @ Y, ubyte hi @ A) clobbers(A,X,Y) = $b391 romsub $b391 = GIVAYF(ubyte lo @ Y, ubyte hi @ A) clobbers(A,X,Y)
asmsub FREADUY (ubyte value @ Y) clobbers(A,X,Y) = $b3a2 ; 8 bit unsigned Y -> float in fac1 romsub $b3a2 = FREADUY(ubyte value @ Y) clobbers(A,X,Y) ; 8 bit unsigned Y -> float in fac1
asmsub FREADSA (byte value @ A) clobbers(A,X,Y) = $bc3c ; 8 bit signed A -> float in fac1 romsub $bc3c = FREADSA(byte value @ A) clobbers(A,X,Y) ; 8 bit signed A -> float in fac1
asmsub FREADSTR (ubyte length @ A) clobbers(A,X,Y) = $b7b5 ; str -> fac1, $22/23 must point to string, A=string length romsub $b7b5 = FREADSTR(ubyte length @ A) clobbers(A,X,Y) ; str -> fac1, $22/23 must point to string, A=string length
asmsub FPRINTLN () clobbers(A,X,Y) = $aabc ; print string of fac1, on one line (= with newline) destroys fac1. (consider FOUT + STROUT as well) romsub $aabc = FPRINTLN() clobbers(A,X,Y) ; print string of fac1, on one line (= with newline) destroys fac1. (consider FOUT + STROUT as well)
asmsub FOUT () clobbers(X) -> uword @ AY = $bddd ; fac1 -> string, address returned in AY ($0100) romsub $bddd = FOUT() clobbers(X) -> uword @ AY ; fac1 -> string, address returned in AY ($0100)
asmsub FADDH () clobbers(A,X,Y) = $b849 ; fac1 += 0.5, for rounding- call this before INT romsub $b849 = FADDH() clobbers(A,X,Y) ; fac1 += 0.5, for rounding- call this before INT
asmsub MUL10 () clobbers(A,X,Y) = $bae2 ; fac1 *= 10 romsub $bae2 = MUL10() clobbers(A,X,Y) ; fac1 *= 10
asmsub DIV10 () clobbers(A,X,Y) = $bafe ; fac1 /= 10 , CAUTION: result is always positive! romsub $bafe = DIV10() clobbers(A,X,Y) ; fac1 /= 10 , CAUTION: result is always positive!
asmsub FCOMP (uword mflpt @ AY) clobbers(X,Y) -> ubyte @ A = $bc5b ; A = compare fac1 to mflpt in A/Y, 0=equal 1=fac1 is greater, 255=fac1 is less than romsub $bc5b = FCOMP(uword mflpt @ AY) clobbers(X,Y) -> ubyte @ A ; A = compare fac1 to mflpt in A/Y, 0=equal 1=fac1 is greater, 255=fac1 is less than
asmsub FADDT () clobbers(A,X,Y) = $b86a ; fac1 += fac2 romsub $b86a = FADDT() clobbers(A,X,Y) ; fac1 += fac2
asmsub FADD (uword mflpt @ AY) clobbers(A,X,Y) = $b867 ; fac1 += mflpt value from A/Y romsub $b867 = FADD(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 += mflpt value from A/Y
asmsub FSUBT () clobbers(A,X,Y) = $b853 ; fac1 = fac2-fac1 mind the order of the operands romsub $b853 = FSUBT() clobbers(A,X,Y) ; fac1 = fac2-fac1 mind the order of the operands
asmsub FSUB (uword mflpt @ AY) clobbers(A,X,Y) = $b850 ; fac1 = mflpt from A/Y - fac1 romsub $b850 = FSUB(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = mflpt from A/Y - fac1
asmsub FMULTT () clobbers(A,X,Y) = $ba2b ; fac1 *= fac2 romsub $ba2b = FMULTT() clobbers(A,X,Y) ; fac1 *= fac2
asmsub FMULT (uword mflpt @ AY) clobbers(A,X,Y) = $ba28 ; fac1 *= mflpt value from A/Y romsub $ba28 = FMULT(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 *= mflpt value from A/Y
asmsub FDIVT () clobbers(A,X,Y) = $bb12 ; fac1 = fac2/fac1 (remainder in fac2) mind the order of the operands romsub $bb12 = FDIVT() clobbers(A,X,Y) ; fac1 = fac2/fac1 (remainder in fac2) mind the order of the operands
asmsub FDIV (uword mflpt @ AY) clobbers(A,X,Y) = $bb0f ; fac1 = mflpt in A/Y / fac1 (remainder in fac2) romsub $bb0f = FDIV(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = mflpt in A/Y / fac1 (remainder in fac2)
asmsub FPWRT () clobbers(A,X,Y) = $bf7b ; fac1 = fac2 ** fac1 romsub $bf7b = FPWRT() clobbers(A,X,Y) ; fac1 = fac2 ** fac1
asmsub FPWR (uword mflpt @ AY) clobbers(A,X,Y) = $bf78 ; fac1 = fac2 ** mflpt from A/Y romsub $bf78 = FPWR(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = fac2 ** mflpt from A/Y
asmsub NOTOP () clobbers(A,X,Y) = $aed4 ; fac1 = NOT(fac1) romsub $aed4 = NOTOP() clobbers(A,X,Y) ; fac1 = NOT(fac1)
asmsub INT () clobbers(A,X,Y) = $bccc ; INT() truncates, use FADDH first to round instead of trunc romsub $bccc = INT() clobbers(A,X,Y) ; INT() truncates, use FADDH first to round instead of trunc
asmsub LOG () clobbers(A,X,Y) = $b9ea ; fac1 = LN(fac1) (natural log) romsub $b9ea = LOG() clobbers(A,X,Y) ; fac1 = LN(fac1) (natural log)
asmsub SGN () clobbers(A,X,Y) = $bc39 ; fac1 = SGN(fac1), result of SIGN (-1, 0 or 1) romsub $bc39 = SGN() clobbers(A,X,Y) ; fac1 = SGN(fac1), result of SIGN (-1, 0 or 1)
asmsub SIGN () -> ubyte @ A = $bc2b ; SIGN(fac1) to A, $ff, $0, $1 for negative, zero, positive romsub $bc2b = SIGN() -> ubyte @ A ; SIGN(fac1) to A, $ff, $0, $1 for negative, zero, positive
asmsub ABS () = $bc58 ; fac1 = ABS(fac1) romsub $bc58 = ABS() ; fac1 = ABS(fac1)
asmsub SQR () clobbers(A,X,Y) = $bf71 ; fac1 = SQRT(fac1) romsub $bf71 = SQR() clobbers(A,X,Y) ; fac1 = SQRT(fac1)
asmsub SQRA () clobbers(A,X,Y) = $bf74 ; fac1 = SQRT(fac2) romsub $bf74 = SQRA() clobbers(A,X,Y) ; fac1 = SQRT(fac2)
asmsub EXP () clobbers(A,X,Y) = $bfed ; fac1 = EXP(fac1) (e ** fac1) romsub $bfed = EXP() clobbers(A,X,Y) ; fac1 = EXP(fac1) (e ** fac1)
asmsub NEGOP () clobbers(A) = $bfb4 ; switch the sign of fac1 romsub $bfb4 = NEGOP() clobbers(A) ; switch the sign of fac1
asmsub RND () clobbers(A,X,Y) = $e097 ; fac1 = RND(fac1) float random number generator romsub $e097 = RND() clobbers(A,X,Y) ; fac1 = RND(fac1) float random number generator
asmsub COS () clobbers(A,X,Y) = $e264 ; fac1 = COS(fac1) romsub $e264 = COS() clobbers(A,X,Y) ; fac1 = COS(fac1)
asmsub SIN () clobbers(A,X,Y) = $e26b ; fac1 = SIN(fac1) romsub $e26b = SIN() clobbers(A,X,Y) ; fac1 = SIN(fac1)
asmsub TAN () clobbers(A,X,Y) = $e2b4 ; fac1 = TAN(fac1) romsub $e2b4 = TAN() clobbers(A,X,Y) ; fac1 = TAN(fac1)
asmsub ATN () clobbers(A,X,Y) = $e30e ; fac1 = ATN(fac1) romsub $e30e = ATN() clobbers(A,X,Y) ; fac1 = ATN(fac1)
asmsub FREADS32() clobbers(A,X,Y) {
asmsub FREADS32 () clobbers(A,X,Y) {
; ---- fac1 = signed int32 from $62-$65 big endian (MSB FIRST) ; ---- fac1 = signed int32 from $62-$65 big endian (MSB FIRST)
%asm {{ %asm {{
lda $62 lda $62

View File

@ -7,178 +7,178 @@
c64 { c64 {
const uword ESTACK_LO = $ce00 ; evaluation stack (lsb) const uword ESTACK_LO = $ce00 ; evaluation stack (lsb)
const uword ESTACK_HI = $cf00 ; evaluation stack (msb) const uword ESTACK_HI = $cf00 ; evaluation stack (msb)
&ubyte SCRATCH_ZPB1 = $02 ; scratch byte 1 in ZP &ubyte SCRATCH_ZPB1 = $02 ; scratch byte 1 in ZP
&ubyte SCRATCH_ZPREG = $03 ; scratch register in ZP &ubyte SCRATCH_ZPREG = $03 ; scratch register in ZP
&ubyte SCRATCH_ZPREGX = $fa ; temp storage for X register (stack pointer) &ubyte SCRATCH_ZPREGX = $fa ; temp storage for X register (stack pointer)
&uword SCRATCH_ZPWORD1 = $fb ; scratch word in ZP ($fb/$fc) &uword SCRATCH_ZPWORD1 = $fb ; scratch word in ZP ($fb/$fc)
&uword SCRATCH_ZPWORD2 = $fd ; scratch word in ZP ($fd/$fe) &uword SCRATCH_ZPWORD2 = $fd ; scratch word in ZP ($fd/$fe)
&ubyte TIME_HI = $a0 ; software jiffy clock, hi byte &ubyte TIME_HI = $a0 ; software jiffy clock, hi byte
&ubyte TIME_MID = $a1 ; .. mid byte &ubyte TIME_MID = $a1 ; .. mid byte
&ubyte TIME_LO = $a2 ; .. lo byte. Updated by IRQ every 1/60 sec &ubyte TIME_LO = $a2 ; .. lo byte. Updated by IRQ every 1/60 sec
&ubyte STKEY = $91 ; various keyboard statuses (updated by IRQ) &ubyte STKEY = $91 ; various keyboard statuses (updated by IRQ)
&ubyte SFDX = $cb ; current key pressed (matrix value) (updated by IRQ) &ubyte SFDX = $cb ; current key pressed (matrix value) (updated by IRQ)
&ubyte COLOR = $0286 ; cursor color &ubyte COLOR = $0286 ; cursor color
&ubyte HIBASE = $0288 ; screen base address / 256 (hi-byte of screen memory address) &ubyte HIBASE = $0288 ; screen base address / 256 (hi-byte of screen memory address)
&uword CINV = $0314 ; IRQ vector &uword CINV = $0314 ; IRQ vector
&uword NMI_VEC = $FFFA ; 6502 nmi vector, determined by the kernal if banked in &uword NMI_VEC = $FFFA ; 6502 nmi vector, determined by the kernal if banked in
&uword RESET_VEC = $FFFC ; 6502 reset vector, determined by the kernal if banked in &uword RESET_VEC = $FFFC ; 6502 reset vector, determined by the kernal if banked in
&uword IRQ_VEC = $FFFE ; 6502 interrupt vector, determined by the kernal if banked in &uword IRQ_VEC = $FFFE ; 6502 interrupt vector, determined by the kernal if banked in
; the default addresses for the character screen chars and colors ; the default addresses for the character screen chars and colors
const uword Screen = $0400 ; to have this as an array[40*25] the compiler would have to support array size > 255 const uword Screen = $0400 ; to have this as an array[40*25] the compiler would have to support array size > 255
const uword Colors = $d800 ; to have this as an array[40*25] the compiler would have to support array size > 255 const uword Colors = $d800 ; to have this as an array[40*25] the compiler would have to support array size > 255
; the default locations of the 8 sprite pointers (store address of sprite / 64) ; the default locations of the 8 sprite pointers (store address of sprite / 64)
&ubyte SPRPTR0 = 2040 &ubyte SPRPTR0 = 2040
&ubyte SPRPTR1 = 2041 &ubyte SPRPTR1 = 2041
&ubyte SPRPTR2 = 2042 &ubyte SPRPTR2 = 2042
&ubyte SPRPTR3 = 2043 &ubyte SPRPTR3 = 2043
&ubyte SPRPTR4 = 2044 &ubyte SPRPTR4 = 2044
&ubyte SPRPTR5 = 2045 &ubyte SPRPTR5 = 2045
&ubyte SPRPTR6 = 2046 &ubyte SPRPTR6 = 2046
&ubyte SPRPTR7 = 2047 &ubyte SPRPTR7 = 2047
&ubyte[8] SPRPTR = 2040 ; the 8 sprite pointers as an array. &ubyte[8] SPRPTR = 2040 ; the 8 sprite pointers as an array.
; ---- VIC-II 6567/6569/856x registers ---- ; ---- VIC-II 6567/6569/856x registers ----
&ubyte SP0X = $d000 &ubyte SP0X = $d000
&ubyte SP0Y = $d001 &ubyte SP0Y = $d001
&ubyte SP1X = $d002 &ubyte SP1X = $d002
&ubyte SP1Y = $d003 &ubyte SP1Y = $d003
&ubyte SP2X = $d004 &ubyte SP2X = $d004
&ubyte SP2Y = $d005 &ubyte SP2Y = $d005
&ubyte SP3X = $d006 &ubyte SP3X = $d006
&ubyte SP3Y = $d007 &ubyte SP3Y = $d007
&ubyte SP4X = $d008 &ubyte SP4X = $d008
&ubyte SP4Y = $d009 &ubyte SP4Y = $d009
&ubyte SP5X = $d00a &ubyte SP5X = $d00a
&ubyte SP5Y = $d00b &ubyte SP5Y = $d00b
&ubyte SP6X = $d00c &ubyte SP6X = $d00c
&ubyte SP6Y = $d00d &ubyte SP6Y = $d00d
&ubyte SP7X = $d00e &ubyte SP7X = $d00e
&ubyte SP7Y = $d00f &ubyte SP7Y = $d00f
&ubyte[16] SPXY = $d000 ; the 8 sprite X and Y registers as an array. &ubyte[16] SPXY = $d000 ; the 8 sprite X and Y registers as an array.
&uword[8] SPXYW = $d000 ; the 8 sprite X and Y registers as a combined xy word array. &uword[8] SPXYW = $d000 ; the 8 sprite X and Y registers as a combined xy word array.
&ubyte MSIGX = $d010 &ubyte MSIGX = $d010
&ubyte SCROLY = $d011 &ubyte SCROLY = $d011
&ubyte RASTER = $d012 &ubyte RASTER = $d012
&ubyte LPENX = $d013 &ubyte LPENX = $d013
&ubyte LPENY = $d014 &ubyte LPENY = $d014
&ubyte SPENA = $d015 &ubyte SPENA = $d015
&ubyte SCROLX = $d016 &ubyte SCROLX = $d016
&ubyte YXPAND = $d017 &ubyte YXPAND = $d017
&ubyte VMCSB = $d018 &ubyte VMCSB = $d018
&ubyte VICIRQ = $d019 &ubyte VICIRQ = $d019
&ubyte IREQMASK = $d01a &ubyte IREQMASK = $d01a
&ubyte SPBGPR = $d01b &ubyte SPBGPR = $d01b
&ubyte SPMC = $d01c &ubyte SPMC = $d01c
&ubyte XXPAND = $d01d &ubyte XXPAND = $d01d
&ubyte SPSPCL = $d01e &ubyte SPSPCL = $d01e
&ubyte SPBGCL = $d01f &ubyte SPBGCL = $d01f
&ubyte EXTCOL = $d020 ; border color &ubyte EXTCOL = $d020 ; border color
&ubyte BGCOL0 = $d021 ; screen color &ubyte BGCOL0 = $d021 ; screen color
&ubyte BGCOL1 = $d022 &ubyte BGCOL1 = $d022
&ubyte BGCOL2 = $d023 &ubyte BGCOL2 = $d023
&ubyte BGCOL4 = $d024 &ubyte BGCOL4 = $d024
&ubyte SPMC0 = $d025 &ubyte SPMC0 = $d025
&ubyte SPMC1 = $d026 &ubyte SPMC1 = $d026
&ubyte SP0COL = $d027 &ubyte SP0COL = $d027
&ubyte SP1COL = $d028 &ubyte SP1COL = $d028
&ubyte SP2COL = $d029 &ubyte SP2COL = $d029
&ubyte SP3COL = $d02a &ubyte SP3COL = $d02a
&ubyte SP4COL = $d02b &ubyte SP4COL = $d02b
&ubyte SP5COL = $d02c &ubyte SP5COL = $d02c
&ubyte SP6COL = $d02d &ubyte SP6COL = $d02d
&ubyte SP7COL = $d02e &ubyte SP7COL = $d02e
&ubyte[8] SPCOL = $d027 &ubyte[8] SPCOL = $d027
; ---- end of VIC-II registers ---- ; ---- end of VIC-II registers ----
; ---- CIA 6526 1 & 2 registers ---- ; ---- CIA 6526 1 & 2 registers ----
&ubyte CIA1PRA = $DC00 ; CIA 1 DRA, keyboard column drive (and joystick control port #2) &ubyte CIA1PRA = $DC00 ; CIA 1 DRA, keyboard column drive (and joystick control port #2)
&ubyte CIA1PRB = $DC01 ; CIA 1 DRB, keyboard row port (and joystick control port #1) &ubyte CIA1PRB = $DC01 ; CIA 1 DRB, keyboard row port (and joystick control port #1)
&ubyte CIA1DDRA = $DC02 ; CIA 1 DDRA, keyboard column &ubyte CIA1DDRA = $DC02 ; CIA 1 DDRA, keyboard column
&ubyte CIA1DDRB = $DC03 ; CIA 1 DDRB, keyboard row &ubyte CIA1DDRB = $DC03 ; CIA 1 DDRB, keyboard row
&ubyte CIA1TAL = $DC04 ; CIA 1 timer A low byte &ubyte CIA1TAL = $DC04 ; CIA 1 timer A low byte
&ubyte CIA1TAH = $DC05 ; CIA 1 timer A high byte &ubyte CIA1TAH = $DC05 ; CIA 1 timer A high byte
&ubyte CIA1TBL = $DC06 ; CIA 1 timer B low byte &ubyte CIA1TBL = $DC06 ; CIA 1 timer B low byte
&ubyte CIA1TBH = $DC07 ; CIA 1 timer B high byte &ubyte CIA1TBH = $DC07 ; CIA 1 timer B high byte
&ubyte CIA1TOD10 = $DC08 ; time of day, 1/10 sec. &ubyte CIA1TOD10 = $DC08 ; time of day, 1/10 sec.
&ubyte CIA1TODSEC = $DC09 ; time of day, seconds &ubyte CIA1TODSEC = $DC09 ; time of day, seconds
&ubyte CIA1TODMMIN = $DC0A ; time of day, minutes &ubyte CIA1TODMMIN = $DC0A ; time of day, minutes
&ubyte CIA1TODHR = $DC0B ; time of day, hours &ubyte CIA1TODHR = $DC0B ; time of day, hours
&ubyte CIA1SDR = $DC0C ; Serial Data Register &ubyte CIA1SDR = $DC0C ; Serial Data Register
&ubyte CIA1ICR = $DC0D &ubyte CIA1ICR = $DC0D
&ubyte CIA1CRA = $DC0E &ubyte CIA1CRA = $DC0E
&ubyte CIA1CRB = $DC0F &ubyte CIA1CRB = $DC0F
&ubyte CIA2PRA = $DD00 ; CIA 2 DRA, serial port and video address &ubyte CIA2PRA = $DD00 ; CIA 2 DRA, serial port and video address
&ubyte CIA2PRB = $DD01 ; CIA 2 DRB, RS232 port / USERPORT &ubyte CIA2PRB = $DD01 ; CIA 2 DRB, RS232 port / USERPORT
&ubyte CIA2DDRA = $DD02 ; CIA 2 DDRA, serial port and video address &ubyte CIA2DDRA = $DD02 ; CIA 2 DDRA, serial port and video address
&ubyte CIA2DDRB = $DD03 ; CIA 2 DDRB, RS232 port / USERPORT &ubyte CIA2DDRB = $DD03 ; CIA 2 DDRB, RS232 port / USERPORT
&ubyte CIA2TAL = $DD04 ; CIA 2 timer A low byte &ubyte CIA2TAL = $DD04 ; CIA 2 timer A low byte
&ubyte CIA2TAH = $DD05 ; CIA 2 timer A high byte &ubyte CIA2TAH = $DD05 ; CIA 2 timer A high byte
&ubyte CIA2TBL = $DD06 ; CIA 2 timer B low byte &ubyte CIA2TBL = $DD06 ; CIA 2 timer B low byte
&ubyte CIA2TBH = $DD07 ; CIA 2 timer B high byte &ubyte CIA2TBH = $DD07 ; CIA 2 timer B high byte
&ubyte CIA2TOD10 = $DD08 ; time of day, 1/10 sec. &ubyte CIA2TOD10 = $DD08 ; time of day, 1/10 sec.
&ubyte CIA2TODSEC = $DD09 ; time of day, seconds &ubyte CIA2TODSEC = $DD09 ; time of day, seconds
&ubyte CIA2TODMIN = $DD0A ; time of day, minutes &ubyte CIA2TODMIN = $DD0A ; time of day, minutes
&ubyte CIA2TODHR = $DD0B ; time of day, hours &ubyte CIA2TODHR = $DD0B ; time of day, hours
&ubyte CIA2SDR = $DD0C ; Serial Data Register &ubyte CIA2SDR = $DD0C ; Serial Data Register
&ubyte CIA2ICR = $DD0D &ubyte CIA2ICR = $DD0D
&ubyte CIA2CRA = $DD0E &ubyte CIA2CRA = $DD0E
&ubyte CIA2CRB = $DD0F &ubyte CIA2CRB = $DD0F
; ---- end of CIA registers ---- ; ---- end of CIA registers ----
; ---- SID 6581/8580 registers ---- ; ---- SID 6581/8580 registers ----
&ubyte FREQLO1 = $D400 ; channel 1 freq lo &ubyte FREQLO1 = $D400 ; channel 1 freq lo
&ubyte FREQHI1 = $D401 ; channel 1 freq hi &ubyte FREQHI1 = $D401 ; channel 1 freq hi
&uword FREQ1 = $D400 ; channel 1 freq (word) &uword FREQ1 = $D400 ; channel 1 freq (word)
&ubyte PWLO1 = $D402 ; channel 1 pulse width lo (7-0) &ubyte PWLO1 = $D402 ; channel 1 pulse width lo (7-0)
&ubyte PWHI1 = $D403 ; channel 1 pulse width hi (11-8) &ubyte PWHI1 = $D403 ; channel 1 pulse width hi (11-8)
&uword PW1 = $D402 ; channel 1 pulse width (word) &uword PW1 = $D402 ; channel 1 pulse width (word)
&ubyte CR1 = $D404 ; channel 1 voice control register &ubyte CR1 = $D404 ; channel 1 voice control register
&ubyte AD1 = $D405 ; channel 1 attack & decay &ubyte AD1 = $D405 ; channel 1 attack & decay
&ubyte SR1 = $D406 ; channel 1 sustain & release &ubyte SR1 = $D406 ; channel 1 sustain & release
&ubyte FREQLO2 = $D407 ; channel 2 freq lo &ubyte FREQLO2 = $D407 ; channel 2 freq lo
&ubyte FREQHI2 = $D408 ; channel 2 freq hi &ubyte FREQHI2 = $D408 ; channel 2 freq hi
&uword FREQ2 = $D407 ; channel 2 freq (word) &uword FREQ2 = $D407 ; channel 2 freq (word)
&ubyte PWLO2 = $D409 ; channel 2 pulse width lo (7-0) &ubyte PWLO2 = $D409 ; channel 2 pulse width lo (7-0)
&ubyte PWHI2 = $D40A ; channel 2 pulse width hi (11-8) &ubyte PWHI2 = $D40A ; channel 2 pulse width hi (11-8)
&uword PW2 = $D409 ; channel 2 pulse width (word) &uword PW2 = $D409 ; channel 2 pulse width (word)
&ubyte CR2 = $D40B ; channel 2 voice control register &ubyte CR2 = $D40B ; channel 2 voice control register
&ubyte AD2 = $D40C ; channel 2 attack & decay &ubyte AD2 = $D40C ; channel 2 attack & decay
&ubyte SR2 = $D40D ; channel 2 sustain & release &ubyte SR2 = $D40D ; channel 2 sustain & release
&ubyte FREQLO3 = $D40E ; channel 3 freq lo &ubyte FREQLO3 = $D40E ; channel 3 freq lo
&ubyte FREQHI3 = $D40F ; channel 3 freq hi &ubyte FREQHI3 = $D40F ; channel 3 freq hi
&uword FREQ3 = $D40E ; channel 3 freq (word) &uword FREQ3 = $D40E ; channel 3 freq (word)
&ubyte PWLO3 = $D410 ; channel 3 pulse width lo (7-0) &ubyte PWLO3 = $D410 ; channel 3 pulse width lo (7-0)
&ubyte PWHI3 = $D411 ; channel 3 pulse width hi (11-8) &ubyte PWHI3 = $D411 ; channel 3 pulse width hi (11-8)
&uword PW3 = $D410 ; channel 3 pulse width (word) &uword PW3 = $D410 ; channel 3 pulse width (word)
&ubyte CR3 = $D412 ; channel 3 voice control register &ubyte CR3 = $D412 ; channel 3 voice control register
&ubyte AD3 = $D413 ; channel 3 attack & decay &ubyte AD3 = $D413 ; channel 3 attack & decay
&ubyte SR3 = $D414 ; channel 3 sustain & release &ubyte SR3 = $D414 ; channel 3 sustain & release
&ubyte FCLO = $D415 ; filter cutoff lo (2-0) &ubyte FCLO = $D415 ; filter cutoff lo (2-0)
&ubyte FCHI = $D416 ; filter cutoff hi (10-3) &ubyte FCHI = $D416 ; filter cutoff hi (10-3)
&uword FC = $D415 ; filter cutoff (word) &uword FC = $D415 ; filter cutoff (word)
&ubyte RESFILT = $D417 ; filter resonance and routing &ubyte RESFILT = $D417 ; filter resonance and routing
&ubyte MVOL = $D418 ; filter mode and main volume control &ubyte MVOL = $D418 ; filter mode and main volume control
&ubyte POTX = $D419 ; potentiometer X &ubyte POTX = $D419 ; potentiometer X
&ubyte POTY = $D41A ; potentiometer Y &ubyte POTY = $D41A ; potentiometer Y
&ubyte OSC3 = $D41B ; channel 3 oscillator value read &ubyte OSC3 = $D41B ; channel 3 oscillator value read
&ubyte ENV3 = $D41C ; channel 3 envelope value read &ubyte ENV3 = $D41C ; channel 3 envelope value read
; ---- end of SID registers ---- ; ---- end of SID registers ----
@ -186,8 +186,8 @@ c64 {
; ---- C64 basic routines ---- ; ---- C64 basic routines ----
asmsub CLEARSCR () clobbers(A,X,Y) = $E544 ; clear the screen romsub $E544 = CLEARSCR() clobbers(A,X,Y) ; clear the screen
asmsub HOMECRSR () clobbers(A,X,Y) = $E566 ; cursor to top left of screen romsub $E566 = HOMECRSR() clobbers(A,X,Y) ; cursor to top left of screen
; ---- end of C64 basic routines ---- ; ---- end of C64 basic routines ----
@ -195,48 +195,48 @@ asmsub HOMECRSR () clobbers(A,X,Y) = $E566 ; cursor to top left of screen
; ---- C64 kernal routines ---- ; ---- C64 kernal routines ----
asmsub STROUT (uword strptr @ AY) clobbers(A, X, Y) = $AB1E ; print null-terminated string (use c64scr.print instead) romsub $AB1E = STROUT(uword strptr @ AY) clobbers(A, X, Y) ; print null-terminated string (use c64scr.print instead)
asmsub IRQDFRT () clobbers(A,X,Y) = $EA31 ; default IRQ routine romsub $EA31 = IRQDFRT() clobbers(A,X,Y) ; default IRQ routine
asmsub IRQDFEND () clobbers(A,X,Y) = $EA81 ; default IRQ end/cleanup romsub $EA81 = IRQDFEND() clobbers(A,X,Y) ; default IRQ end/cleanup
asmsub CINT () clobbers(A,X,Y) = $FF81 ; (alias: SCINIT) initialize screen editor and video chip romsub $FF81 = CINT() clobbers(A,X,Y) ; (alias: SCINIT) initialize screen editor and video chip
asmsub IOINIT () clobbers(A, X) = $FF84 ; initialize I/O devices (CIA, SID, IRQ) romsub $FF84 = IOINIT() clobbers(A, X) ; initialize I/O devices (CIA, SID, IRQ)
asmsub RAMTAS () clobbers(A,X,Y) = $FF87 ; initialize RAM, tape buffer, screen romsub $FF87 = RAMTAS() clobbers(A,X,Y) ; initialize RAM, tape buffer, screen
asmsub RESTOR () clobbers(A,X,Y) = $FF8A ; restore default I/O vectors romsub $FF8A = RESTOR() clobbers(A,X,Y) ; restore default I/O vectors
asmsub VECTOR (uword userptr @ XY, ubyte dir @ Pc) clobbers(A,Y) = $FF8D ; read/set I/O vector table romsub $FF8D = VECTOR(uword userptr @ XY, ubyte dir @ Pc) clobbers(A,Y) ; read/set I/O vector table
asmsub SETMSG (ubyte value @ A) = $FF90 ; set Kernal message control flag romsub $FF90 = SETMSG(ubyte value @ A) ; set Kernal message control flag
asmsub SECOND (ubyte address @ A) clobbers(A) = $FF93 ; (alias: LSTNSA) send secondary address after LISTEN romsub $FF93 = SECOND(ubyte address @ A) clobbers(A) ; (alias: LSTNSA) send secondary address after LISTEN
asmsub TKSA (ubyte address @ A) clobbers(A) = $FF96 ; (alias: TALKSA) send secondary address after TALK romsub $FF96 = TKSA(ubyte address @ A) clobbers(A) ; (alias: TALKSA) send secondary address after TALK
asmsub MEMTOP (uword address @ XY, ubyte dir @ Pc) -> uword @ XY = $FF99 ; read/set top of memory pointer romsub $FF99 = MEMTOP(uword address @ XY, ubyte dir @ Pc) -> uword @ XY ; read/set top of memory pointer
asmsub MEMBOT (uword address @ XY, ubyte dir @ Pc) -> uword @ XY = $FF9C ; read/set bottom of memory pointer romsub $FF9C = MEMBOT(uword address @ XY, ubyte dir @ Pc) -> uword @ XY ; read/set bottom of memory pointer
asmsub SCNKEY () clobbers(A,X,Y) = $FF9F ; scan the keyboard romsub $FF9F = SCNKEY() clobbers(A,X,Y) ; scan the keyboard
asmsub SETTMO (ubyte timeout @ A) = $FFA2 ; set time-out flag for IEEE bus romsub $FFA2 = SETTMO(ubyte timeout @ A) ; set time-out flag for IEEE bus
asmsub ACPTR () -> ubyte @ A = $FFA5 ; (alias: IECIN) input byte from serial bus romsub $FFA5 = ACPTR() -> ubyte @ A ; (alias: IECIN) input byte from serial bus
asmsub CIOUT (ubyte databyte @ A) = $FFA8 ; (alias: IECOUT) output byte to serial bus romsub $FFA8 = CIOUT(ubyte databyte @ A) ; (alias: IECOUT) output byte to serial bus
asmsub UNTLK () clobbers(A) = $FFAB ; command serial bus device to UNTALK romsub $FFAB = UNTLK() clobbers(A) ; command serial bus device to UNTALK
asmsub UNLSN () clobbers(A) = $FFAE ; command serial bus device to UNLISTEN romsub $FFAE = UNLSN() clobbers(A) ; command serial bus device to UNLISTEN
asmsub LISTEN (ubyte device @ A) clobbers(A) = $FFB1 ; command serial bus device to LISTEN romsub $FFB1 = LISTEN(ubyte device @ A) clobbers(A) ; command serial bus device to LISTEN
asmsub TALK (ubyte device @ A) clobbers(A) = $FFB4 ; command serial bus device to TALK romsub $FFB4 = TALK(ubyte device @ A) clobbers(A) ; command serial bus device to TALK
asmsub READST () -> ubyte @ A = $FFB7 ; read I/O status word romsub $FFB7 = READST() -> ubyte @ A ; read I/O status word
asmsub SETLFS (ubyte logical @ A, ubyte device @ X, ubyte address @ Y) = $FFBA ; set logical file parameters romsub $FFBA = SETLFS(ubyte logical @ A, ubyte device @ X, ubyte address @ Y) ; set logical file parameters
asmsub SETNAM (ubyte namelen @ A, str filename @ XY) = $FFBD ; set filename parameters romsub $FFBD = SETNAM(ubyte namelen @ A, str filename @ XY) ; set filename parameters
asmsub OPEN () clobbers(A,X,Y) = $FFC0 ; (via 794 ($31A)) open a logical file romsub $FFC0 = OPEN() clobbers(A,X,Y) ; (via 794 ($31A)) open a logical file
asmsub CLOSE (ubyte logical @ A) clobbers(A,X,Y) = $FFC3 ; (via 796 ($31C)) close a logical file romsub $FFC3 = CLOSE(ubyte logical @ A) clobbers(A,X,Y) ; (via 796 ($31C)) close a logical file
asmsub CHKIN (ubyte logical @ X) clobbers(A,X) = $FFC6 ; (via 798 ($31E)) define an input channel romsub $FFC6 = CHKIN(ubyte logical @ X) clobbers(A,X) ; (via 798 ($31E)) define an input channel
asmsub CHKOUT (ubyte logical @ X) clobbers(A,X) = $FFC9 ; (via 800 ($320)) define an output channel romsub $FFC9 = CHKOUT(ubyte logical @ X) clobbers(A,X) ; (via 800 ($320)) define an output channel
asmsub CLRCHN () clobbers(A,X) = $FFCC ; (via 802 ($322)) restore default devices romsub $FFCC = CLRCHN() clobbers(A,X) ; (via 802 ($322)) restore default devices
asmsub CHRIN () clobbers(Y) -> ubyte @ A = $FFCF ; (via 804 ($324)) input a character (for keyboard, read a whole line from the screen) A=byte read. romsub $FFCF = CHRIN() clobbers(Y) -> ubyte @ A ; (via 804 ($324)) input a character (for keyboard, read a whole line from the screen) A=byte read.
asmsub CHROUT (ubyte char @ A) = $FFD2 ; (via 806 ($326)) output a character romsub $FFD2 = CHROUT(ubyte char @ A) ; (via 806 ($326)) output a character
asmsub LOAD (ubyte verify @ A, uword address @ XY) -> ubyte @Pc, ubyte @ A, ubyte @ X, ubyte @ Y = $FFD5 ; (via 816 ($330)) load from device romsub $FFD5 = LOAD(ubyte verify @ A, uword address @ XY) -> ubyte @Pc, ubyte @ A, ubyte @ X, ubyte @ Y ; (via 816 ($330)) load from device
asmsub SAVE (ubyte zp_startaddr @ A, uword endaddr @ XY) -> ubyte @ Pc, ubyte @ A = $FFD8 ; (via 818 ($332)) save to a device romsub $FFD8 = SAVE(ubyte zp_startaddr @ A, uword endaddr @ XY) -> ubyte @ Pc, ubyte @ A ; (via 818 ($332)) save to a device
asmsub SETTIM (ubyte low @ A, ubyte middle @ X, ubyte high @ Y) = $FFDB ; set the software clock romsub $FFDB = SETTIM(ubyte low @ A, ubyte middle @ X, ubyte high @ Y) ; set the software clock
asmsub RDTIM () -> ubyte @ A, ubyte @ X, ubyte @ Y = $FFDE ; read the software clock romsub $FFDE = RDTIM() -> ubyte @ A, ubyte @ X, ubyte @ Y ; read the software clock
asmsub STOP () clobbers(A,X) -> ubyte @ Pz, ubyte @ Pc = $FFE1 ; (via 808 ($328)) check the STOP key romsub $FFE1 = STOP() clobbers(A,X) -> ubyte @ Pz, ubyte @ Pc ; (via 808 ($328)) check the STOP key
asmsub GETIN () clobbers(X,Y) -> ubyte @ A = $FFE4 ; (via 810 ($32A)) get a character romsub $FFE4 = GETIN() clobbers(X,Y) -> ubyte @ A ; (via 810 ($32A)) get a character
asmsub CLALL () clobbers(A,X) = $FFE7 ; (via 812 ($32C)) close all files romsub $FFE7 = CLALL() clobbers(A,X) ; (via 812 ($32C)) close all files
asmsub UDTIM () clobbers(A,X) = $FFEA ; update the software clock romsub $FFEA = UDTIM() clobbers(A,X) ; update the software clock
asmsub SCREEN () -> ubyte @ X, ubyte @ Y = $FFED ; read number of screen rows and columns romsub $FFED = SCREEN() -> ubyte @ X, ubyte @ Y ; read number of screen rows and columns
asmsub PLOT (ubyte col @ Y, ubyte row @ X, ubyte dir @ Pc) -> ubyte @ X, ubyte @ Y = $FFF0 ; read/set position of cursor on screen. Use c64scr.plot for a 'safe' wrapper that preserves X. romsub $FFF0 = PLOT(ubyte col @ Y, ubyte row @ X, ubyte dir @ Pc) -> ubyte @ X, ubyte @ Y ; read/set position of cursor on screen. Use c64scr.plot for a 'safe' wrapper that preserves X.
asmsub IOBASE () -> uword @ XY = $FFF3 ; read base address of I/O devices romsub $FFF3 = IOBASE() -> uword @ XY ; read base address of I/O devices
; ---- end of C64 kernal routines ---- ; ---- end of C64 kernal routines ----

View File

@ -202,6 +202,9 @@ private fun prog8Parser.StatementContext.toAst() : Statement {
val asmsubstmt = asmsubroutine()?.toAst() val asmsubstmt = asmsubroutine()?.toAst()
if(asmsubstmt!=null) return asmsubstmt if(asmsubstmt!=null) return asmsubstmt
val romsubstmt = romsubroutine()?.toAst()
if(romsubstmt!=null) return romsubstmt
val whenstmt = whenstmt()?.toAst() val whenstmt = whenstmt()?.toAst()
if(whenstmt!=null) return whenstmt if(whenstmt!=null) return whenstmt
@ -215,20 +218,43 @@ private fun prog8Parser.StatementContext.toAst() : Statement {
} }
private fun prog8Parser.AsmsubroutineContext.toAst(): Statement { private fun prog8Parser.AsmsubroutineContext.toAst(): Statement {
val subdecl = asmsub_decl().toAst()
val statements = statement_block()?.toAst() ?: mutableListOf()
return Subroutine(subdecl.name, subdecl.parameters, subdecl.returntypes,
subdecl.asmParameterRegisters, subdecl.asmReturnvaluesRegisters,
subdecl.asmClobbers, null, true, statements, toPosition())
}
private fun prog8Parser.RomsubroutineContext.toAst(): Statement {
val subdecl = asmsub_decl().toAst()
val address = integerliteral().toAst().number.toInt()
return Subroutine(subdecl.name, subdecl.parameters, subdecl.returntypes,
subdecl.asmParameterRegisters, subdecl.asmReturnvaluesRegisters,
subdecl.asmClobbers, address, true, mutableListOf(), toPosition())
}
private class AsmsubDecl(val name: String,
val parameters: List<SubroutineParameter>,
val returntypes: List<DataType>,
val asmParameterRegisters: List<RegisterOrStatusflag>,
val asmReturnvaluesRegisters: List<RegisterOrStatusflag>,
val asmClobbers: Set<Register>)
private fun prog8Parser.Asmsub_declContext.toAst(): AsmsubDecl {
val name = identifier().text val name = identifier().text
val address = asmsub_address()?.address?.toAst()?.number?.toInt()
val params = asmsub_params()?.toAst() ?: emptyList() val params = asmsub_params()?.toAst() ?: emptyList()
val returns = asmsub_returns()?.toAst() ?: emptyList() val returns = asmsub_returns()?.toAst() ?: emptyList()
val clobbers = asmsub_clobbers()?.clobber()?.toAst() ?: emptySet()
val normalParameters = params.map { SubroutineParameter(it.name, it.type, it.position) } val normalParameters = params.map { SubroutineParameter(it.name, it.type, it.position) }
val normalReturnvalues = returns.map { it.type } val normalReturntypes = returns.map { it.type }
val paramRegisters = params.map { RegisterOrStatusflag(it.registerOrPair, it.statusflag, it.stack) } val paramRegisters = params.map { RegisterOrStatusflag(it.registerOrPair, it.statusflag, it.stack) }
val returnRegisters = returns.map { RegisterOrStatusflag(it.registerOrPair, it.statusflag, it.stack) } val returnRegisters = returns.map { RegisterOrStatusflag(it.registerOrPair, it.statusflag, it.stack) }
val clobbers = asmsub_clobbers()?.clobber()?.toAst() ?: emptySet() return AsmsubDecl(name, normalParameters, normalReturntypes, paramRegisters, returnRegisters, clobbers)
val statements = statement_block()?.toAst() ?: mutableListOf()
return Subroutine(name, normalParameters, normalReturnvalues,
paramRegisters, returnRegisters, clobbers, address, true, statements, toPosition())
} }
private class AsmSubroutineParameter(name: String, private class AsmSubroutineParameter(name: String,
type: DataType, type: DataType,
val registerOrPair: RegisterOrPair?, val registerOrPair: RegisterOrPair?,

View File

@ -594,6 +594,7 @@ class Subroutine(override val name: String,
.count { " rti" in it || "\trti" in it || " rts" in it || "\trts" in it || " jmp" in it || "\tjmp" in it } .count { " rti" in it || "\trti" in it || " rts" in it || "\trts" in it || " jmp" in it || "\tjmp" in it }
} }
open class SubroutineParameter(val name: String, open class SubroutineParameter(val name: String,
val type: DataType, val type: DataType,
override val position: Position) : Node { override val position: Position) : Node {

View File

@ -464,9 +464,9 @@ If you're not interested in the return value, prefix the function call with the
Otherwise the compiler will warn you about discarding the result of the call. Otherwise the compiler will warn you about discarding the result of the call.
Normal subroutines can only return zero or one return values. Normal subroutines can only return zero or one return values.
However, the special ``asmsub`` routines (implemented in assembly code or referencing However, the special ``asmsub`` routines (implemented in assembly code) or ``romsub`` routines
a routine in kernel ROM) can return more than one return values, for instance a status (referencing a routine in kernel ROM) can return more than one return value.
in the carry bit and a number in A, or a 16-bit value in A/Y registers. For example a status in the carry bit and a number in A, or a 16-bit value in A/Y registers.
It is not possible to process the results of a call to these kind of routines It is not possible to process the results of a call to these kind of routines
directly from the language, because only single value assignments are possible. directly from the language, because only single value assignments are possible.
You can still call the subroutine and not store the results. You can still call the subroutine and not store the results.
@ -494,9 +494,34 @@ and can have nothing following it. The close curly brace must be on its own line
The parameters is a (possibly empty) comma separated list of "<datatype> <parametername>" pairs specifying the input parameters. The parameters is a (possibly empty) comma separated list of "<datatype> <parametername>" pairs specifying the input parameters.
The return type has to be specified if the subroutine returns a value. The return type has to be specified if the subroutine returns a value.
.. todo::
asmsub with assigning memory address to refer to predefined ROM subroutines Assembly / ROM subroutines
asmsub with a regular body to precisely control what registers are used to call the subroutine ^^^^^^^^^^^^^^^^^^^^^^^^^^^
Subroutines implemented in ROM are usually defined by compiler library files, with the following syntax::
romsub $FFD5 = LOAD(ubyte verify @ A, uword address @ XY) -> clobbers() -> ubyte @Pc, ubyte @ A, ubyte @ X, ubyte @ Y
This defines the ``LOAD`` subroutine at ROM memory address $FFD5, taking arguments in all three registers A, X and Y,
and returning stuff in several registers as well. The ``clobbers`` clause is used to signify to the compiler
what CPU registers are clobbered by the call instead of being unchanged or returning a meaningful result value.
Subroutines that are implemented purely in assembly code and which have an assembly calling convention (i.e.
the parameters are strictly passed via cpu registers), are defined like this::
asmsub FREADS32() clobbers(A,X,Y) {
%asm {{
lda $62
eor #$ff
asl a
lda #0
ldx #$a0
jmp $bc4f
}}
}
the statement body of such a subroutine should consist of just an inline assembly block.
Expressions Expressions

View File

@ -89,6 +89,7 @@ statement :
| branch_stmt | branch_stmt
| subroutine | subroutine
| asmsubroutine | asmsubroutine
| romsubroutine
| inlineasm | inlineasm
| returnstmt | returnstmt
| forloop | forloop
@ -256,11 +257,14 @@ sub_params : vardecl (',' EOL? vardecl)* ;
sub_returns : datatype (',' EOL? datatype)* ; sub_returns : datatype (',' EOL? datatype)* ;
asmsubroutine : asmsubroutine :
'asmsub' identifier '(' asmsub_params? ')' EOL? 'asmsub' asmsub_decl statement_block
asmsub_clobbers? asmsub_returns? (asmsub_address | statement_block )
; ;
asmsub_address : '=' address=integerliteral ; romsubroutine :
'romsub' integerliteral '=' asmsub_decl
;
asmsub_decl : identifier '(' asmsub_params? ')' asmsub_clobbers? asmsub_returns? ;
asmsub_params : asmsub_param (',' EOL? asmsub_param)* ; asmsub_params : asmsub_param (',' EOL? asmsub_param)* ;

View File

@ -34,10 +34,10 @@ public class prog8Lexer extends Lexer {
T__87=88, T__88=89, T__89=90, T__90=91, T__91=92, T__92=93, T__93=94, T__87=88, T__88=89, T__89=90, T__90=91, T__91=92, T__92=93, T__93=94,
T__94=95, T__95=96, T__96=97, T__97=98, T__98=99, T__99=100, T__100=101, T__94=95, T__95=96, T__96=97, T__97=98, T__98=99, T__99=100, T__100=101,
T__101=102, T__102=103, T__103=104, T__104=105, T__105=106, T__106=107, T__101=102, T__102=103, T__103=104, T__104=105, T__105=106, T__106=107,
T__107=108, T__108=109, LINECOMMENT=110, COMMENT=111, WS=112, EOL=113, T__107=108, T__108=109, T__109=110, LINECOMMENT=111, COMMENT=112, WS=113,
VOID=114, NAME=115, DEC_INTEGER=116, HEX_INTEGER=117, BIN_INTEGER=118, EOL=114, VOID=115, NAME=116, DEC_INTEGER=117, HEX_INTEGER=118, BIN_INTEGER=119,
ADDRESS_OF=119, FLOAT_NUMBER=120, STRING=121, INLINEASMBLOCK=122, SINGLECHAR=123, ADDRESS_OF=120, FLOAT_NUMBER=121, STRING=122, INLINEASMBLOCK=123, SINGLECHAR=124,
ZEROPAGE=124, ARRAYSIG=125; ZEROPAGE=125, ARRAYSIG=126;
public static String[] channelNames = { public static String[] channelNames = {
"DEFAULT_TOKEN_CHANNEL", "HIDDEN" "DEFAULT_TOKEN_CHANNEL", "HIDDEN"
}; };
@ -61,10 +61,10 @@ public class prog8Lexer extends Lexer {
"T__81", "T__82", "T__83", "T__84", "T__85", "T__86", "T__87", "T__88", "T__81", "T__82", "T__83", "T__84", "T__85", "T__86", "T__87", "T__88",
"T__89", "T__90", "T__91", "T__92", "T__93", "T__94", "T__95", "T__96", "T__89", "T__90", "T__91", "T__92", "T__93", "T__94", "T__95", "T__96",
"T__97", "T__98", "T__99", "T__100", "T__101", "T__102", "T__103", "T__104", "T__97", "T__98", "T__99", "T__100", "T__101", "T__102", "T__103", "T__104",
"T__105", "T__106", "T__107", "T__108", "LINECOMMENT", "COMMENT", "WS", "T__105", "T__106", "T__107", "T__108", "T__109", "LINECOMMENT", "COMMENT",
"EOL", "VOID", "NAME", "DEC_INTEGER", "HEX_INTEGER", "BIN_INTEGER", "ADDRESS_OF", "WS", "EOL", "VOID", "NAME", "DEC_INTEGER", "HEX_INTEGER", "BIN_INTEGER",
"FLOAT_NUMBER", "FNUMBER", "STRING_ESCAPE_SEQ", "STRING", "INLINEASMBLOCK", "ADDRESS_OF", "FLOAT_NUMBER", "FNUMBER", "STRING_ESCAPE_SEQ", "STRING",
"SINGLECHAR", "ZEROPAGE", "ARRAYSIG" "INLINEASMBLOCK", "SINGLECHAR", "ZEROPAGE", "ARRAYSIG"
}; };
} }
public static final String[] ruleNames = makeRuleNames(); public static final String[] ruleNames = makeRuleNames();
@ -81,12 +81,12 @@ public class prog8Lexer extends Lexer {
"'|'", "'to'", "'step'", "'and'", "'or'", "'xor'", "'not'", "'('", "')'", "'|'", "'to'", "'step'", "'and'", "'or'", "'xor'", "'not'", "'('", "')'",
"'as'", "'@'", "'return'", "'break'", "'continue'", "'.'", "'A'", "'X'", "'as'", "'@'", "'return'", "'break'", "'continue'", "'.'", "'A'", "'X'",
"'Y'", "'AX'", "'AY'", "'XY'", "'Pc'", "'Pz'", "'Pn'", "'Pv'", "'.w'", "'Y'", "'AX'", "'AY'", "'XY'", "'Pc'", "'Pz'", "'Pn'", "'Pv'", "'.w'",
"'true'", "'false'", "'%asm'", "'sub'", "'->'", "'asmsub'", "'stack'", "'true'", "'false'", "'%asm'", "'sub'", "'->'", "'asmsub'", "'romsub'",
"'clobbers'", "'if'", "'else'", "'if_cs'", "'if_cc'", "'if_eq'", "'if_z'", "'stack'", "'clobbers'", "'if'", "'else'", "'if_cs'", "'if_cc'", "'if_eq'",
"'if_ne'", "'if_nz'", "'if_pl'", "'if_pos'", "'if_mi'", "'if_neg'", "'if_vs'", "'if_z'", "'if_ne'", "'if_nz'", "'if_pl'", "'if_pos'", "'if_mi'", "'if_neg'",
"'if_vc'", "'for'", "'in'", "'while'", "'repeat'", "'until'", "'when'", "'if_vs'", "'if_vc'", "'for'", "'in'", "'while'", "'repeat'", "'until'",
null, null, null, null, "'void'", null, null, null, null, "'&'", null, "'when'", null, null, null, null, "'void'", null, null, null, null, "'&'",
null, null, null, "'@zp'", "'[]'" null, null, null, null, "'@zp'", "'[]'"
}; };
} }
private static final String[] _LITERAL_NAMES = makeLiteralNames(); private static final String[] _LITERAL_NAMES = makeLiteralNames();
@ -101,9 +101,9 @@ public class prog8Lexer extends Lexer {
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, "LINECOMMENT", "COMMENT", "WS", "EOL", "VOID", "NAME", "DEC_INTEGER", null, null, null, "LINECOMMENT", "COMMENT", "WS", "EOL", "VOID", "NAME",
"HEX_INTEGER", "BIN_INTEGER", "ADDRESS_OF", "FLOAT_NUMBER", "STRING", "DEC_INTEGER", "HEX_INTEGER", "BIN_INTEGER", "ADDRESS_OF", "FLOAT_NUMBER",
"INLINEASMBLOCK", "SINGLECHAR", "ZEROPAGE", "ARRAYSIG" "STRING", "INLINEASMBLOCK", "SINGLECHAR", "ZEROPAGE", "ARRAYSIG"
}; };
} }
private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
@ -167,13 +167,13 @@ public class prog8Lexer extends Lexer {
@Override @Override
public void action(RuleContext _localctx, int ruleIndex, int actionIndex) { public void action(RuleContext _localctx, int ruleIndex, int actionIndex) {
switch (ruleIndex) { switch (ruleIndex) {
case 122: case 123:
STRING_action((RuleContext)_localctx, actionIndex); STRING_action((RuleContext)_localctx, actionIndex);
break; break;
case 123: case 124:
INLINEASMBLOCK_action((RuleContext)_localctx, actionIndex); INLINEASMBLOCK_action((RuleContext)_localctx, actionIndex);
break; break;
case 124: case 125:
SINGLECHAR_action((RuleContext)_localctx, actionIndex); SINGLECHAR_action((RuleContext)_localctx, actionIndex);
break; break;
} }
@ -213,9 +213,9 @@ public class prog8Lexer extends Lexer {
} }
public static final String _serializedATN = public static final String _serializedATN =
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\177\u036d\b\1\4\2"+ "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\u0080\u0376\b\1\4"+
"\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4"+ "\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n"+
"\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22"+ "\4\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22"+
"\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31"+ "\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31"+
"\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t"+ "\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t"+
" \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t"+ " \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t"+
@ -227,283 +227,286 @@ public class prog8Lexer extends Lexer {
"\4`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4g\tg\4h\th\4i\ti\4j\tj\4k"+ "\4`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4g\tg\4h\th\4i\ti\4j\tj\4k"+
"\tk\4l\tl\4m\tm\4n\tn\4o\to\4p\tp\4q\tq\4r\tr\4s\ts\4t\tt\4u\tu\4v\tv"+ "\tk\4l\tl\4m\tm\4n\tn\4o\to\4p\tp\4q\tq\4r\tr\4s\ts\4t\tt\4u\tu\4v\tv"+
"\4w\tw\4x\tx\4y\ty\4z\tz\4{\t{\4|\t|\4}\t}\4~\t~\4\177\t\177\4\u0080\t"+ "\4w\tw\4x\tx\4y\ty\4z\tz\4{\t{\4|\t|\4}\t}\4~\t~\4\177\t\177\4\u0080\t"+
"\u0080\3\2\3\2\3\3\3\3\3\3\3\3\3\3\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\5"+ "\u0080\4\u0081\t\u0081\3\2\3\2\3\3\3\3\3\3\3\3\3\3\3\4\3\4\3\4\3\4\3\4"+
"\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3"+ "\3\4\3\4\3\4\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\6\3\6\3\6\3\6\3"+
"\6\3\6\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\b\3\b\3\b\3\b"+ "\6\3\6\3\6\3\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7"+
"\3\b\3\b\3\b\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\n\3\n\3\n\3\n\3"+ "\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3"+
"\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13"+ "\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\13\3\13\3\13\3\13\3\13"+
"\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\r\3"+ "\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3"+
"\r\3\r\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\17\3\17\3\20\3\20\3\20\3\20\3\20"+ "\f\3\f\3\f\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\17\3\17\3\20\3"+
"\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\23\3\23\3\24\3\24"+ "\20\3\20\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3"+
"\3\24\3\24\3\24\3\24\3\25\3\25\3\25\3\25\3\25\3\26\3\26\3\26\3\26\3\26"+ "\23\3\23\3\24\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3\25\3\25\3\25\3\26\3"+
"\3\26\3\27\3\27\3\27\3\27\3\27\3\30\3\30\3\30\3\30\3\30\3\30\3\31\3\31"+ "\26\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3\27\3\27\3\30\3\30\3\30\3\30\3"+
"\3\31\3\31\3\32\3\32\3\33\3\33\3\34\3\34\3\34\3\35\3\35\3\35\3\36\3\36"+ "\30\3\30\3\31\3\31\3\31\3\31\3\32\3\32\3\33\3\33\3\34\3\34\3\34\3\35\3"+
"\3\36\3\37\3\37\3\37\3 \3 \3 \3 \3!\3!\3!\3\"\3\"\3\"\3#\3#\3#\3$\3$\3"+ "\35\3\35\3\36\3\36\3\36\3\37\3\37\3\37\3 \3 \3 \3 \3!\3!\3!\3\"\3\"\3"+
"$\3%\3%\3%\3%\3&\3&\3&\3&\3\'\3\'\3\'\3(\3(\3(\3)\3)\3*\3*\3+\3+\3,\3"+ "\"\3#\3#\3#\3$\3$\3$\3%\3%\3%\3%\3&\3&\3&\3&\3\'\3\'\3\'\3(\3(\3(\3)\3"+
",\3,\3-\3-\3.\3.\3/\3/\3\60\3\60\3\60\3\61\3\61\3\61\3\62\3\62\3\63\3"+ ")\3*\3*\3+\3+\3,\3,\3,\3-\3-\3.\3.\3/\3/\3\60\3\60\3\60\3\61\3\61\3\61"+
"\63\3\64\3\64\3\64\3\65\3\65\3\65\3\66\3\66\3\66\3\67\3\67\3\67\38\38"+ "\3\62\3\62\3\63\3\63\3\64\3\64\3\64\3\65\3\65\3\65\3\66\3\66\3\66\3\67"+
"\39\39\3:\3:\3:\3;\3;\3;\3;\3;\3<\3<\3<\3<\3=\3=\3=\3>\3>\3>\3>\3?\3?"+ "\3\67\3\67\38\38\39\39\3:\3:\3:\3;\3;\3;\3;\3;\3<\3<\3<\3<\3=\3=\3=\3"+
"\3?\3?\3@\3@\3A\3A\3B\3B\3B\3C\3C\3D\3D\3D\3D\3D\3D\3D\3E\3E\3E\3E\3E"+ ">\3>\3>\3>\3?\3?\3?\3?\3@\3@\3A\3A\3B\3B\3B\3C\3C\3D\3D\3D\3D\3D\3D\3"+
"\3E\3F\3F\3F\3F\3F\3F\3F\3F\3F\3G\3G\3H\3H\3I\3I\3J\3J\3K\3K\3K\3L\3L"+ "D\3E\3E\3E\3E\3E\3E\3F\3F\3F\3F\3F\3F\3F\3F\3F\3G\3G\3H\3H\3I\3I\3J\3"+
"\3L\3M\3M\3M\3N\3N\3N\3O\3O\3O\3P\3P\3P\3Q\3Q\3Q\3R\3R\3R\3S\3S\3S\3S"+ "J\3K\3K\3K\3L\3L\3L\3M\3M\3M\3N\3N\3N\3O\3O\3O\3P\3P\3P\3Q\3Q\3Q\3R\3"+
"\3S\3T\3T\3T\3T\3T\3T\3U\3U\3U\3U\3U\3V\3V\3V\3V\3W\3W\3W\3X\3X\3X\3X"+ "R\3R\3S\3S\3S\3S\3S\3T\3T\3T\3T\3T\3T\3U\3U\3U\3U\3U\3V\3V\3V\3V\3W\3"+
"\3X\3X\3X\3Y\3Y\3Y\3Y\3Y\3Y\3Z\3Z\3Z\3Z\3Z\3Z\3Z\3Z\3Z\3[\3[\3[\3\\\3"+ "W\3W\3X\3X\3X\3X\3X\3X\3X\3Y\3Y\3Y\3Y\3Y\3Y\3Y\3Z\3Z\3Z\3Z\3Z\3Z\3[\3"+
"\\\3\\\3\\\3\\\3]\3]\3]\3]\3]\3]\3^\3^\3^\3^\3^\3^\3_\3_\3_\3_\3_\3_\3"+ "[\3[\3[\3[\3[\3[\3[\3[\3\\\3\\\3\\\3]\3]\3]\3]\3]\3^\3^\3^\3^\3^\3^\3"+
"`\3`\3`\3`\3`\3a\3a\3a\3a\3a\3a\3b\3b\3b\3b\3b\3b\3c\3c\3c\3c\3c\3c\3"+ "_\3_\3_\3_\3_\3_\3`\3`\3`\3`\3`\3`\3a\3a\3a\3a\3a\3b\3b\3b\3b\3b\3b\3"+
"d\3d\3d\3d\3d\3d\3d\3e\3e\3e\3e\3e\3e\3f\3f\3f\3f\3f\3f\3f\3g\3g\3g\3"+ "c\3c\3c\3c\3c\3c\3d\3d\3d\3d\3d\3d\3e\3e\3e\3e\3e\3e\3e\3f\3f\3f\3f\3"+
"g\3g\3g\3h\3h\3h\3h\3h\3h\3i\3i\3i\3i\3j\3j\3j\3k\3k\3k\3k\3k\3k\3l\3"+ "f\3f\3g\3g\3g\3g\3g\3g\3g\3h\3h\3h\3h\3h\3h\3i\3i\3i\3i\3i\3i\3j\3j\3"+
"l\3l\3l\3l\3l\3l\3m\3m\3m\3m\3m\3m\3n\3n\3n\3n\3n\3o\3o\7o\u02ee\no\f"+ "j\3j\3k\3k\3k\3l\3l\3l\3l\3l\3l\3m\3m\3m\3m\3m\3m\3m\3n\3n\3n\3n\3n\3"+
"o\16o\u02f1\13o\3o\3o\3o\3o\3p\3p\7p\u02f9\np\fp\16p\u02fc\13p\3p\3p\3"+ "n\3o\3o\3o\3o\3o\3p\3p\7p\u02f7\np\fp\16p\u02fa\13p\3p\3p\3p\3p\3q\3q"+
"q\3q\3q\3q\3r\6r\u0305\nr\rr\16r\u0306\3s\3s\3s\3s\3s\3t\3t\7t\u0310\n"+ "\7q\u0302\nq\fq\16q\u0305\13q\3q\3q\3r\3r\3r\3r\3s\6s\u030e\ns\rs\16s"+
"t\ft\16t\u0313\13t\3u\3u\3u\6u\u0318\nu\ru\16u\u0319\5u\u031c\nu\3v\3"+ "\u030f\3t\3t\3t\3t\3t\3u\3u\7u\u0319\nu\fu\16u\u031c\13u\3v\3v\3v\6v\u0321"+
"v\6v\u0320\nv\rv\16v\u0321\3w\3w\6w\u0326\nw\rw\16w\u0327\3x\3x\3y\3y"+ "\nv\rv\16v\u0322\5v\u0325\nv\3w\3w\6w\u0329\nw\rw\16w\u032a\3x\3x\6x\u032f"+
"\3y\5y\u032f\ny\3y\5y\u0332\ny\3z\6z\u0335\nz\rz\16z\u0336\3z\3z\6z\u033b"+ "\nx\rx\16x\u0330\3y\3y\3z\3z\3z\5z\u0338\nz\3z\5z\u033b\nz\3{\6{\u033e"+
"\nz\rz\16z\u033c\5z\u033f\nz\3{\3{\3{\3{\5{\u0345\n{\3|\3|\3|\7|\u034a"+ "\n{\r{\16{\u033f\3{\3{\6{\u0344\n{\r{\16{\u0345\5{\u0348\n{\3|\3|\3|\3"+
"\n|\f|\16|\u034d\13|\3|\3|\3|\3}\3}\3}\3}\6}\u0356\n}\r}\16}\u0357\3}"+ "|\5|\u034e\n|\3}\3}\3}\7}\u0353\n}\f}\16}\u0356\13}\3}\3}\3}\3~\3~\3~"+
"\3}\3}\3}\3}\3~\3~\3~\5~\u0362\n~\3~\3~\3~\3\177\3\177\3\177\3\177\3\u0080"+ "\3~\6~\u035f\n~\r~\16~\u0360\3~\3~\3~\3~\3~\3\177\3\177\3\177\5\177\u036b"+
"\3\u0080\3\u0080\3\u0357\2\u0081\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23"+ "\n\177\3\177\3\177\3\177\3\u0080\3\u0080\3\u0080\3\u0080\3\u0081\3\u0081"+
"\13\25\f\27\r\31\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31"+ "\3\u0081\3\u0360\2\u0082\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f"+
"\61\32\63\33\65\34\67\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60"+ "\27\r\31\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63"+
"_\61a\62c\63e\64g\65i\66k\67m8o9q:s;u<w=y>{?}@\177A\u0081B\u0083C\u0085"+ "\33\65\34\67\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62"+
"D\u0087E\u0089F\u008bG\u008dH\u008fI\u0091J\u0093K\u0095L\u0097M\u0099"+ "c\63e\64g\65i\66k\67m8o9q:s;u<w=y>{?}@\177A\u0081B\u0083C\u0085D\u0087"+
"N\u009bO\u009dP\u009fQ\u00a1R\u00a3S\u00a5T\u00a7U\u00a9V\u00abW\u00ad"+ "E\u0089F\u008bG\u008dH\u008fI\u0091J\u0093K\u0095L\u0097M\u0099N\u009b"+
"X\u00afY\u00b1Z\u00b3[\u00b5\\\u00b7]\u00b9^\u00bb_\u00bd`\u00bfa\u00c1"+ "O\u009dP\u009fQ\u00a1R\u00a3S\u00a5T\u00a7U\u00a9V\u00abW\u00adX\u00af"+
"b\u00c3c\u00c5d\u00c7e\u00c9f\u00cbg\u00cdh\u00cfi\u00d1j\u00d3k\u00d5"+ "Y\u00b1Z\u00b3[\u00b5\\\u00b7]\u00b9^\u00bb_\u00bd`\u00bfa\u00c1b\u00c3"+
"l\u00d7m\u00d9n\u00dbo\u00ddp\u00dfq\u00e1r\u00e3s\u00e5t\u00e7u\u00e9"+ "c\u00c5d\u00c7e\u00c9f\u00cbg\u00cdh\u00cfi\u00d1j\u00d3k\u00d5l\u00d7"+
"v\u00ebw\u00edx\u00efy\u00f1z\u00f3\2\u00f5\2\u00f7{\u00f9|\u00fb}\u00fd"+ "m\u00d9n\u00dbo\u00ddp\u00dfq\u00e1r\u00e3s\u00e5t\u00e7u\u00e9v\u00eb"+
"~\u00ff\177\3\2\n\4\2\f\f\17\17\4\2\13\13\"\"\5\2C\\aac|\6\2\62;C\\aa"+ "w\u00edx\u00efy\u00f1z\u00f3{\u00f5\2\u00f7\2\u00f9|\u00fb}\u00fd~\u00ff"+
"c|\5\2\62;CHch\4\2GGgg\4\2--//\6\2\f\f\16\17$$^^\2\u037c\2\3\3\2\2\2\2"+ "\177\u0101\u0080\3\2\n\4\2\f\f\17\17\4\2\13\13\"\"\5\2C\\aac|\6\2\62;"+
"\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2"+ "C\\aac|\5\2\62;CHch\4\2GGgg\4\2--//\6\2\f\f\16\17$$^^\2\u0385\2\3\3\2"+
"\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2"+ "\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17"+
"\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2"+ "\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2"+
"\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2"+ "\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3"+
"\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2"+ "\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3"+
"\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2"+ "\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2"+
"K\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3"+ "=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3"+
"\2\2\2\2Y\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2"+ "\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2"+
"\2\2e\3\2\2\2\2g\3\2\2\2\2i\3\2\2\2\2k\3\2\2\2\2m\3\2\2\2\2o\3\2\2\2\2"+ "\2\2W\3\2\2\2\2Y\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2"+
"q\3\2\2\2\2s\3\2\2\2\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3"+ "c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2i\3\2\2\2\2k\3\2\2\2\2m\3\2\2\2\2o\3"+
"\2\2\2\2\177\3\2\2\2\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2\u0085\3\2\2\2\2"+ "\2\2\2\2q\3\2\2\2\2s\3\2\2\2\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2"+
"\u0087\3\2\2\2\2\u0089\3\2\2\2\2\u008b\3\2\2\2\2\u008d\3\2\2\2\2\u008f"+ "\2\2}\3\2\2\2\2\177\3\2\2\2\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2\u0085\3"+
"\3\2\2\2\2\u0091\3\2\2\2\2\u0093\3\2\2\2\2\u0095\3\2\2\2\2\u0097\3\2\2"+ "\2\2\2\2\u0087\3\2\2\2\2\u0089\3\2\2\2\2\u008b\3\2\2\2\2\u008d\3\2\2\2"+
"\2\2\u0099\3\2\2\2\2\u009b\3\2\2\2\2\u009d\3\2\2\2\2\u009f\3\2\2\2\2\u00a1"+ "\2\u008f\3\2\2\2\2\u0091\3\2\2\2\2\u0093\3\2\2\2\2\u0095\3\2\2\2\2\u0097"+
"\3\2\2\2\2\u00a3\3\2\2\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9\3\2\2"+ "\3\2\2\2\2\u0099\3\2\2\2\2\u009b\3\2\2\2\2\u009d\3\2\2\2\2\u009f\3\2\2"+
"\2\2\u00ab\3\2\2\2\2\u00ad\3\2\2\2\2\u00af\3\2\2\2\2\u00b1\3\2\2\2\2\u00b3"+ "\2\2\u00a1\3\2\2\2\2\u00a3\3\2\2\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9"+
"\3\2\2\2\2\u00b5\3\2\2\2\2\u00b7\3\2\2\2\2\u00b9\3\2\2\2\2\u00bb\3\2\2"+ "\3\2\2\2\2\u00ab\3\2\2\2\2\u00ad\3\2\2\2\2\u00af\3\2\2\2\2\u00b1\3\2\2"+
"\2\2\u00bd\3\2\2\2\2\u00bf\3\2\2\2\2\u00c1\3\2\2\2\2\u00c3\3\2\2\2\2\u00c5"+ "\2\2\u00b3\3\2\2\2\2\u00b5\3\2\2\2\2\u00b7\3\2\2\2\2\u00b9\3\2\2\2\2\u00bb"+
"\3\2\2\2\2\u00c7\3\2\2\2\2\u00c9\3\2\2\2\2\u00cb\3\2\2\2\2\u00cd\3\2\2"+ "\3\2\2\2\2\u00bd\3\2\2\2\2\u00bf\3\2\2\2\2\u00c1\3\2\2\2\2\u00c3\3\2\2"+
"\2\2\u00cf\3\2\2\2\2\u00d1\3\2\2\2\2\u00d3\3\2\2\2\2\u00d5\3\2\2\2\2\u00d7"+ "\2\2\u00c5\3\2\2\2\2\u00c7\3\2\2\2\2\u00c9\3\2\2\2\2\u00cb\3\2\2\2\2\u00cd"+
"\3\2\2\2\2\u00d9\3\2\2\2\2\u00db\3\2\2\2\2\u00dd\3\2\2\2\2\u00df\3\2\2"+ "\3\2\2\2\2\u00cf\3\2\2\2\2\u00d1\3\2\2\2\2\u00d3\3\2\2\2\2\u00d5\3\2\2"+
"\2\2\u00e1\3\2\2\2\2\u00e3\3\2\2\2\2\u00e5\3\2\2\2\2\u00e7\3\2\2\2\2\u00e9"+ "\2\2\u00d7\3\2\2\2\2\u00d9\3\2\2\2\2\u00db\3\2\2\2\2\u00dd\3\2\2\2\2\u00df"+
"\3\2\2\2\2\u00eb\3\2\2\2\2\u00ed\3\2\2\2\2\u00ef\3\2\2\2\2\u00f1\3\2\2"+ "\3\2\2\2\2\u00e1\3\2\2\2\2\u00e3\3\2\2\2\2\u00e5\3\2\2\2\2\u00e7\3\2\2"+
"\2\2\u00f7\3\2\2\2\2\u00f9\3\2\2\2\2\u00fb\3\2\2\2\2\u00fd\3\2\2\2\2\u00ff"+ "\2\2\u00e9\3\2\2\2\2\u00eb\3\2\2\2\2\u00ed\3\2\2\2\2\u00ef\3\2\2\2\2\u00f1"+
"\3\2\2\2\3\u0101\3\2\2\2\5\u0103\3\2\2\2\7\u0108\3\2\2\2\t\u0110\3\2\2"+ "\3\2\2\2\2\u00f3\3\2\2\2\2\u00f9\3\2\2\2\2\u00fb\3\2\2\2\2\u00fd\3\2\2"+
"\2\13\u011a\3\2\2\2\r\u0124\3\2\2\2\17\u0130\3\2\2\2\21\u0139\3\2\2\2"+ "\2\2\u00ff\3\2\2\2\2\u0101\3\2\2\2\3\u0103\3\2\2\2\5\u0105\3\2\2\2\7\u010a"+
"\23\u0141\3\2\2\2\25\u014d\3\2\2\2\27\u0159\3\2\2\2\31\u0164\3\2\2\2\33"+ "\3\2\2\2\t\u0112\3\2\2\2\13\u011c\3\2\2\2\r\u0126\3\2\2\2\17\u0132\3\2"+
"\u016c\3\2\2\2\35\u016e\3\2\2\2\37\u0170\3\2\2\2!\u0176\3\2\2\2#\u017d"+ "\2\2\21\u013b\3\2\2\2\23\u0143\3\2\2\2\25\u014f\3\2\2\2\27\u015b\3\2\2"+
"\3\2\2\2%\u017f\3\2\2\2\'\u0181\3\2\2\2)\u0187\3\2\2\2+\u018c\3\2\2\2"+ "\2\31\u0166\3\2\2\2\33\u016e\3\2\2\2\35\u0170\3\2\2\2\37\u0172\3\2\2\2"+
"-\u0192\3\2\2\2/\u0197\3\2\2\2\61\u019d\3\2\2\2\63\u01a1\3\2\2\2\65\u01a3"+ "!\u0178\3\2\2\2#\u017f\3\2\2\2%\u0181\3\2\2\2\'\u0183\3\2\2\2)\u0189\3"+
"\3\2\2\2\67\u01a5\3\2\2\29\u01a8\3\2\2\2;\u01ab\3\2\2\2=\u01ae\3\2\2\2"+ "\2\2\2+\u018e\3\2\2\2-\u0194\3\2\2\2/\u0199\3\2\2\2\61\u019f\3\2\2\2\63"+
"?\u01b1\3\2\2\2A\u01b5\3\2\2\2C\u01b8\3\2\2\2E\u01bb\3\2\2\2G\u01be\3"+ "\u01a3\3\2\2\2\65\u01a5\3\2\2\2\67\u01a7\3\2\2\29\u01aa\3\2\2\2;\u01ad"+
"\2\2\2I\u01c1\3\2\2\2K\u01c5\3\2\2\2M\u01c9\3\2\2\2O\u01cc\3\2\2\2Q\u01cf"+ "\3\2\2\2=\u01b0\3\2\2\2?\u01b3\3\2\2\2A\u01b7\3\2\2\2C\u01ba\3\2\2\2E"+
"\3\2\2\2S\u01d1\3\2\2\2U\u01d3\3\2\2\2W\u01d5\3\2\2\2Y\u01d8\3\2\2\2["+ "\u01bd\3\2\2\2G\u01c0\3\2\2\2I\u01c3\3\2\2\2K\u01c7\3\2\2\2M\u01cb\3\2"+
"\u01da\3\2\2\2]\u01dc\3\2\2\2_\u01de\3\2\2\2a\u01e1\3\2\2\2c\u01e4\3\2"+ "\2\2O\u01ce\3\2\2\2Q\u01d1\3\2\2\2S\u01d3\3\2\2\2U\u01d5\3\2\2\2W\u01d7"+
"\2\2e\u01e6\3\2\2\2g\u01e8\3\2\2\2i\u01eb\3\2\2\2k\u01ee\3\2\2\2m\u01f1"+ "\3\2\2\2Y\u01da\3\2\2\2[\u01dc\3\2\2\2]\u01de\3\2\2\2_\u01e0\3\2\2\2a"+
"\3\2\2\2o\u01f4\3\2\2\2q\u01f6\3\2\2\2s\u01f8\3\2\2\2u\u01fb\3\2\2\2w"+ "\u01e3\3\2\2\2c\u01e6\3\2\2\2e\u01e8\3\2\2\2g\u01ea\3\2\2\2i\u01ed\3\2"+
"\u0200\3\2\2\2y\u0204\3\2\2\2{\u0207\3\2\2\2}\u020b\3\2\2\2\177\u020f"+ "\2\2k\u01f0\3\2\2\2m\u01f3\3\2\2\2o\u01f6\3\2\2\2q\u01f8\3\2\2\2s\u01fa"+
"\3\2\2\2\u0081\u0211\3\2\2\2\u0083\u0213\3\2\2\2\u0085\u0216\3\2\2\2\u0087"+ "\3\2\2\2u\u01fd\3\2\2\2w\u0202\3\2\2\2y\u0206\3\2\2\2{\u0209\3\2\2\2}"+
"\u0218\3\2\2\2\u0089\u021f\3\2\2\2\u008b\u0225\3\2\2\2\u008d\u022e\3\2"+ "\u020d\3\2\2\2\177\u0211\3\2\2\2\u0081\u0213\3\2\2\2\u0083\u0215\3\2\2"+
"\2\2\u008f\u0230\3\2\2\2\u0091\u0232\3\2\2\2\u0093\u0234\3\2\2\2\u0095"+ "\2\u0085\u0218\3\2\2\2\u0087\u021a\3\2\2\2\u0089\u0221\3\2\2\2\u008b\u0227"+
"\u0236\3\2\2\2\u0097\u0239\3\2\2\2\u0099\u023c\3\2\2\2\u009b\u023f\3\2"+ "\3\2\2\2\u008d\u0230\3\2\2\2\u008f\u0232\3\2\2\2\u0091\u0234\3\2\2\2\u0093"+
"\2\2\u009d\u0242\3\2\2\2\u009f\u0245\3\2\2\2\u00a1\u0248\3\2\2\2\u00a3"+ "\u0236\3\2\2\2\u0095\u0238\3\2\2\2\u0097\u023b\3\2\2\2\u0099\u023e\3\2"+
"\u024b\3\2\2\2\u00a5\u024e\3\2\2\2\u00a7\u0253\3\2\2\2\u00a9\u0259\3\2"+ "\2\2\u009b\u0241\3\2\2\2\u009d\u0244\3\2\2\2\u009f\u0247\3\2\2\2\u00a1"+
"\2\2\u00ab\u025e\3\2\2\2\u00ad\u0262\3\2\2\2\u00af\u0265\3\2\2\2\u00b1"+ "\u024a\3\2\2\2\u00a3\u024d\3\2\2\2\u00a5\u0250\3\2\2\2\u00a7\u0255\3\2"+
"\u026c\3\2\2\2\u00b3\u0272\3\2\2\2\u00b5\u027b\3\2\2\2\u00b7\u027e\3\2"+ "\2\2\u00a9\u025b\3\2\2\2\u00ab\u0260\3\2\2\2\u00ad\u0264\3\2\2\2\u00af"+
"\2\2\u00b9\u0283\3\2\2\2\u00bb\u0289\3\2\2\2\u00bd\u028f\3\2\2\2\u00bf"+ "\u0267\3\2\2\2\u00b1\u026e\3\2\2\2\u00b3\u0275\3\2\2\2\u00b5\u027b\3\2"+
"\u0295\3\2\2\2\u00c1\u029a\3\2\2\2\u00c3\u02a0\3\2\2\2\u00c5\u02a6\3\2"+ "\2\2\u00b7\u0284\3\2\2\2\u00b9\u0287\3\2\2\2\u00bb\u028c\3\2\2\2\u00bd"+
"\2\2\u00c7\u02ac\3\2\2\2\u00c9\u02b3\3\2\2\2\u00cb\u02b9\3\2\2\2\u00cd"+ "\u0292\3\2\2\2\u00bf\u0298\3\2\2\2\u00c1\u029e\3\2\2\2\u00c3\u02a3\3\2"+
"\u02c0\3\2\2\2\u00cf\u02c6\3\2\2\2\u00d1\u02cc\3\2\2\2\u00d3\u02d0\3\2"+ "\2\2\u00c5\u02a9\3\2\2\2\u00c7\u02af\3\2\2\2\u00c9\u02b5\3\2\2\2\u00cb"+
"\2\2\u00d5\u02d3\3\2\2\2\u00d7\u02d9\3\2\2\2\u00d9\u02e0\3\2\2\2\u00db"+ "\u02bc\3\2\2\2\u00cd\u02c2\3\2\2\2\u00cf\u02c9\3\2\2\2\u00d1\u02cf\3\2"+
"\u02e6\3\2\2\2\u00dd\u02eb\3\2\2\2\u00df\u02f6\3\2\2\2\u00e1\u02ff\3\2"+ "\2\2\u00d3\u02d5\3\2\2\2\u00d5\u02d9\3\2\2\2\u00d7\u02dc\3\2\2\2\u00d9"+
"\2\2\u00e3\u0304\3\2\2\2\u00e5\u0308\3\2\2\2\u00e7\u030d\3\2\2\2\u00e9"+ "\u02e2\3\2\2\2\u00db\u02e9\3\2\2\2\u00dd\u02ef\3\2\2\2\u00df\u02f4\3\2"+
"\u031b\3\2\2\2\u00eb\u031d\3\2\2\2\u00ed\u0323\3\2\2\2\u00ef\u0329\3\2"+ "\2\2\u00e1\u02ff\3\2\2\2\u00e3\u0308\3\2\2\2\u00e5\u030d\3\2\2\2\u00e7"+
"\2\2\u00f1\u032b\3\2\2\2\u00f3\u0334\3\2\2\2\u00f5\u0344\3\2\2\2\u00f7"+ "\u0311\3\2\2\2\u00e9\u0316\3\2\2\2\u00eb\u0324\3\2\2\2\u00ed\u0326\3\2"+
"\u0346\3\2\2\2\u00f9\u0351\3\2\2\2\u00fb\u035e\3\2\2\2\u00fd\u0366\3\2"+ "\2\2\u00ef\u032c\3\2\2\2\u00f1\u0332\3\2\2\2\u00f3\u0334\3\2\2\2\u00f5"+
"\2\2\u00ff\u036a\3\2\2\2\u0101\u0102\7<\2\2\u0102\4\3\2\2\2\u0103\u0104"+ "\u033d\3\2\2\2\u00f7\u034d\3\2\2\2\u00f9\u034f\3\2\2\2\u00fb\u035a\3\2"+
"\7i\2\2\u0104\u0105\7q\2\2\u0105\u0106\7v\2\2\u0106\u0107\7q\2\2\u0107"+ "\2\2\u00fd\u0367\3\2\2\2\u00ff\u036f\3\2\2\2\u0101\u0373\3\2\2\2\u0103"+
"\6\3\2\2\2\u0108\u0109\7\'\2\2\u0109\u010a\7q\2\2\u010a\u010b\7w\2\2\u010b"+ "\u0104\7<\2\2\u0104\4\3\2\2\2\u0105\u0106\7i\2\2\u0106\u0107\7q\2\2\u0107"+
"\u010c\7v\2\2\u010c\u010d\7r\2\2\u010d\u010e\7w\2\2\u010e\u010f\7v\2\2"+ "\u0108\7v\2\2\u0108\u0109\7q\2\2\u0109\6\3\2\2\2\u010a\u010b\7\'\2\2\u010b"+
"\u010f\b\3\2\2\2\u0110\u0111\7\'\2\2\u0111\u0112\7n\2\2\u0112\u0113\7"+ "\u010c\7q\2\2\u010c\u010d\7w\2\2\u010d\u010e\7v\2\2\u010e\u010f\7r\2\2"+
"c\2\2\u0113\u0114\7w\2\2\u0114\u0115\7p\2\2\u0115\u0116\7e\2\2\u0116\u0117"+ "\u010f\u0110\7w\2\2\u0110\u0111\7v\2\2\u0111\b\3\2\2\2\u0112\u0113\7\'"+
"\7j\2\2\u0117\u0118\7g\2\2\u0118\u0119\7t\2\2\u0119\n\3\2\2\2\u011a\u011b"+ "\2\2\u0113\u0114\7n\2\2\u0114\u0115\7c\2\2\u0115\u0116\7w\2\2\u0116\u0117"+
"\7\'\2\2\u011b\u011c\7|\2\2\u011c\u011d\7g\2\2\u011d\u011e\7t\2\2\u011e"+ "\7p\2\2\u0117\u0118\7e\2\2\u0118\u0119\7j\2\2\u0119\u011a\7g\2\2\u011a"+
"\u011f\7q\2\2\u011f\u0120\7r\2\2\u0120\u0121\7c\2\2\u0121\u0122\7i\2\2"+ "\u011b\7t\2\2\u011b\n\3\2\2\2\u011c\u011d\7\'\2\2\u011d\u011e\7|\2\2\u011e"+
"\u0122\u0123\7g\2\2\u0123\f\3\2\2\2\u0124\u0125\7\'\2\2\u0125\u0126\7"+ "\u011f\7g\2\2\u011f\u0120\7t\2\2\u0120\u0121\7q\2\2\u0121\u0122\7r\2\2"+
"|\2\2\u0126\u0127\7r\2\2\u0127\u0128\7t\2\2\u0128\u0129\7g\2\2\u0129\u012a"+ "\u0122\u0123\7c\2\2\u0123\u0124\7i\2\2\u0124\u0125\7g\2\2\u0125\f\3\2"+
"\7u\2\2\u012a\u012b\7g\2\2\u012b\u012c\7t\2\2\u012c\u012d\7x\2\2\u012d"+ "\2\2\u0126\u0127\7\'\2\2\u0127\u0128\7|\2\2\u0128\u0129\7r\2\2\u0129\u012a"+
"\u012e\7g\2\2\u012e\u012f\7f\2\2\u012f\16\3\2\2\2\u0130\u0131\7\'\2\2"+ "\7t\2\2\u012a\u012b\7g\2\2\u012b\u012c\7u\2\2\u012c\u012d\7g\2\2\u012d"+
"\u0131\u0132\7c\2\2\u0132\u0133\7f\2\2\u0133\u0134\7f\2\2\u0134\u0135"+ "\u012e\7t\2\2\u012e\u012f\7x\2\2\u012f\u0130\7g\2\2\u0130\u0131\7f\2\2"+
"\7t\2\2\u0135\u0136\7g\2\2\u0136\u0137\7u\2\2\u0137\u0138\7u\2\2\u0138"+ "\u0131\16\3\2\2\2\u0132\u0133\7\'\2\2\u0133\u0134\7c\2\2\u0134\u0135\7"+
"\20\3\2\2\2\u0139\u013a\7\'\2\2\u013a\u013b\7k\2\2\u013b\u013c\7o\2\2"+ "f\2\2\u0135\u0136\7f\2\2\u0136\u0137\7t\2\2\u0137\u0138\7g\2\2\u0138\u0139"+
"\u013c\u013d\7r\2\2\u013d\u013e\7q\2\2\u013e\u013f\7t\2\2\u013f\u0140"+ "\7u\2\2\u0139\u013a\7u\2\2\u013a\20\3\2\2\2\u013b\u013c\7\'\2\2\u013c"+
"\7v\2\2\u0140\22\3\2\2\2\u0141\u0142\7\'\2\2\u0142\u0143\7d\2\2\u0143"+ "\u013d\7k\2\2\u013d\u013e\7o\2\2\u013e\u013f\7r\2\2\u013f\u0140\7q\2\2"+
"\u0144\7t\2\2\u0144\u0145\7g\2\2\u0145\u0146\7c\2\2\u0146\u0147\7m\2\2"+ "\u0140\u0141\7t\2\2\u0141\u0142\7v\2\2\u0142\22\3\2\2\2\u0143\u0144\7"+
"\u0147\u0148\7r\2\2\u0148\u0149\7q\2\2\u0149\u014a\7k\2\2\u014a\u014b"+ "\'\2\2\u0144\u0145\7d\2\2\u0145\u0146\7t\2\2\u0146\u0147\7g\2\2\u0147"+
"\7p\2\2\u014b\u014c\7v\2\2\u014c\24\3\2\2\2\u014d\u014e\7\'\2\2\u014e"+ "\u0148\7c\2\2\u0148\u0149\7m\2\2\u0149\u014a\7r\2\2\u014a\u014b\7q\2\2"+
"\u014f\7c\2\2\u014f\u0150\7u\2\2\u0150\u0151\7o\2\2\u0151\u0152\7k\2\2"+ "\u014b\u014c\7k\2\2\u014c\u014d\7p\2\2\u014d\u014e\7v\2\2\u014e\24\3\2"+
"\u0152\u0153\7p\2\2\u0153\u0154\7e\2\2\u0154\u0155\7n\2\2\u0155\u0156"+ "\2\2\u014f\u0150\7\'\2\2\u0150\u0151\7c\2\2\u0151\u0152\7u\2\2\u0152\u0153"+
"\7w\2\2\u0156\u0157\7f\2\2\u0157\u0158\7g\2\2\u0158\26\3\2\2\2\u0159\u015a"+ "\7o\2\2\u0153\u0154\7k\2\2\u0154\u0155\7p\2\2\u0155\u0156\7e\2\2\u0156"+
"\7\'\2\2\u015a\u015b\7c\2\2\u015b\u015c\7u\2\2\u015c\u015d\7o\2\2\u015d"+ "\u0157\7n\2\2\u0157\u0158\7w\2\2\u0158\u0159\7f\2\2\u0159\u015a\7g\2\2"+
"\u015e\7d\2\2\u015e\u015f\7k\2\2\u015f\u0160\7p\2\2\u0160\u0161\7c\2\2"+ "\u015a\26\3\2\2\2\u015b\u015c\7\'\2\2\u015c\u015d\7c\2\2\u015d\u015e\7"+
"\u0161\u0162\7t\2\2\u0162\u0163\7{\2\2\u0163\30\3\2\2\2\u0164\u0165\7"+ "u\2\2\u015e\u015f\7o\2\2\u015f\u0160\7d\2\2\u0160\u0161\7k\2\2\u0161\u0162"+
"\'\2\2\u0165\u0166\7q\2\2\u0166\u0167\7r\2\2\u0167\u0168\7v\2\2\u0168"+ "\7p\2\2\u0162\u0163\7c\2\2\u0163\u0164\7t\2\2\u0164\u0165\7{\2\2\u0165"+
"\u0169\7k\2\2\u0169\u016a\7q\2\2\u016a\u016b\7p\2\2\u016b\32\3\2\2\2\u016c"+ "\30\3\2\2\2\u0166\u0167\7\'\2\2\u0167\u0168\7q\2\2\u0168\u0169\7r\2\2"+
"\u016d\7.\2\2\u016d\34\3\2\2\2\u016e\u016f\7?\2\2\u016f\36\3\2\2\2\u0170"+ "\u0169\u016a\7v\2\2\u016a\u016b\7k\2\2\u016b\u016c\7q\2\2\u016c\u016d"+
"\u0171\7e\2\2\u0171\u0172\7q\2\2\u0172\u0173\7p\2\2\u0173\u0174\7u\2\2"+ "\7p\2\2\u016d\32\3\2\2\2\u016e\u016f\7.\2\2\u016f\34\3\2\2\2\u0170\u0171"+
"\u0174\u0175\7v\2\2\u0175 \3\2\2\2\u0176\u0177\7u\2\2\u0177\u0178\7v\2"+ "\7?\2\2\u0171\36\3\2\2\2\u0172\u0173\7e\2\2\u0173\u0174\7q\2\2\u0174\u0175"+
"\2\u0178\u0179\7t\2\2\u0179\u017a\7w\2\2\u017a\u017b\7e\2\2\u017b\u017c"+ "\7p\2\2\u0175\u0176\7u\2\2\u0176\u0177\7v\2\2\u0177 \3\2\2\2\u0178\u0179"+
"\7v\2\2\u017c\"\3\2\2\2\u017d\u017e\7}\2\2\u017e$\3\2\2\2\u017f\u0180"+ "\7u\2\2\u0179\u017a\7v\2\2\u017a\u017b\7t\2\2\u017b\u017c\7w\2\2\u017c"+
"\7\177\2\2\u0180&\3\2\2\2\u0181\u0182\7w\2\2\u0182\u0183\7d\2\2\u0183"+ "\u017d\7e\2\2\u017d\u017e\7v\2\2\u017e\"\3\2\2\2\u017f\u0180\7}\2\2\u0180"+
"\u0184\7{\2\2\u0184\u0185\7v\2\2\u0185\u0186\7g\2\2\u0186(\3\2\2\2\u0187"+ "$\3\2\2\2\u0181\u0182\7\177\2\2\u0182&\3\2\2\2\u0183\u0184\7w\2\2\u0184"+
"\u0188\7d\2\2\u0188\u0189\7{\2\2\u0189\u018a\7v\2\2\u018a\u018b\7g\2\2"+ "\u0185\7d\2\2\u0185\u0186\7{\2\2\u0186\u0187\7v\2\2\u0187\u0188\7g\2\2"+
"\u018b*\3\2\2\2\u018c\u018d\7w\2\2\u018d\u018e\7y\2\2\u018e\u018f\7q\2"+ "\u0188(\3\2\2\2\u0189\u018a\7d\2\2\u018a\u018b\7{\2\2\u018b\u018c\7v\2"+
"\2\u018f\u0190\7t\2\2\u0190\u0191\7f\2\2\u0191,\3\2\2\2\u0192\u0193\7"+ "\2\u018c\u018d\7g\2\2\u018d*\3\2\2\2\u018e\u018f\7w\2\2\u018f\u0190\7"+
"y\2\2\u0193\u0194\7q\2\2\u0194\u0195\7t\2\2\u0195\u0196\7f\2\2\u0196."+ "y\2\2\u0190\u0191\7q\2\2\u0191\u0192\7t\2\2\u0192\u0193\7f\2\2\u0193,"+
"\3\2\2\2\u0197\u0198\7h\2\2\u0198\u0199\7n\2\2\u0199\u019a\7q\2\2\u019a"+ "\3\2\2\2\u0194\u0195\7y\2\2\u0195\u0196\7q\2\2\u0196\u0197\7t\2\2\u0197"+
"\u019b\7c\2\2\u019b\u019c\7v\2\2\u019c\60\3\2\2\2\u019d\u019e\7u\2\2\u019e"+ "\u0198\7f\2\2\u0198.\3\2\2\2\u0199\u019a\7h\2\2\u019a\u019b\7n\2\2\u019b"+
"\u019f\7v\2\2\u019f\u01a0\7t\2\2\u01a0\62\3\2\2\2\u01a1\u01a2\7]\2\2\u01a2"+ "\u019c\7q\2\2\u019c\u019d\7c\2\2\u019d\u019e\7v\2\2\u019e\60\3\2\2\2\u019f"+
"\64\3\2\2\2\u01a3\u01a4\7_\2\2\u01a4\66\3\2\2\2\u01a5\u01a6\7-\2\2\u01a6"+ "\u01a0\7u\2\2\u01a0\u01a1\7v\2\2\u01a1\u01a2\7t\2\2\u01a2\62\3\2\2\2\u01a3"+
"\u01a7\7?\2\2\u01a78\3\2\2\2\u01a8\u01a9\7/\2\2\u01a9\u01aa\7?\2\2\u01aa"+ "\u01a4\7]\2\2\u01a4\64\3\2\2\2\u01a5\u01a6\7_\2\2\u01a6\66\3\2\2\2\u01a7"+
":\3\2\2\2\u01ab\u01ac\7\61\2\2\u01ac\u01ad\7?\2\2\u01ad<\3\2\2\2\u01ae"+ "\u01a8\7-\2\2\u01a8\u01a9\7?\2\2\u01a98\3\2\2\2\u01aa\u01ab\7/\2\2\u01ab"+
"\u01af\7,\2\2\u01af\u01b0\7?\2\2\u01b0>\3\2\2\2\u01b1\u01b2\7,\2\2\u01b2"+ "\u01ac\7?\2\2\u01ac:\3\2\2\2\u01ad\u01ae\7\61\2\2\u01ae\u01af\7?\2\2\u01af"+
"\u01b3\7,\2\2\u01b3\u01b4\7?\2\2\u01b4@\3\2\2\2\u01b5\u01b6\7(\2\2\u01b6"+ "<\3\2\2\2\u01b0\u01b1\7,\2\2\u01b1\u01b2\7?\2\2\u01b2>\3\2\2\2\u01b3\u01b4"+
"\u01b7\7?\2\2\u01b7B\3\2\2\2\u01b8\u01b9\7~\2\2\u01b9\u01ba\7?\2\2\u01ba"+ "\7,\2\2\u01b4\u01b5\7,\2\2\u01b5\u01b6\7?\2\2\u01b6@\3\2\2\2\u01b7\u01b8"+
"D\3\2\2\2\u01bb\u01bc\7`\2\2\u01bc\u01bd\7?\2\2\u01bdF\3\2\2\2\u01be\u01bf"+ "\7(\2\2\u01b8\u01b9\7?\2\2\u01b9B\3\2\2\2\u01ba\u01bb\7~\2\2\u01bb\u01bc"+
"\7\'\2\2\u01bf\u01c0\7?\2\2\u01c0H\3\2\2\2\u01c1\u01c2\7>\2\2\u01c2\u01c3"+ "\7?\2\2\u01bcD\3\2\2\2\u01bd\u01be\7`\2\2\u01be\u01bf\7?\2\2\u01bfF\3"+
"\7>\2\2\u01c3\u01c4\7?\2\2\u01c4J\3\2\2\2\u01c5\u01c6\7@\2\2\u01c6\u01c7"+ "\2\2\2\u01c0\u01c1\7\'\2\2\u01c1\u01c2\7?\2\2\u01c2H\3\2\2\2\u01c3\u01c4"+
"\7@\2\2\u01c7\u01c8\7?\2\2\u01c8L\3\2\2\2\u01c9\u01ca\7-\2\2\u01ca\u01cb"+ "\7>\2\2\u01c4\u01c5\7>\2\2\u01c5\u01c6\7?\2\2\u01c6J\3\2\2\2\u01c7\u01c8"+
"\7-\2\2\u01cbN\3\2\2\2\u01cc\u01cd\7/\2\2\u01cd\u01ce\7/\2\2\u01ceP\3"+ "\7@\2\2\u01c8\u01c9\7@\2\2\u01c9\u01ca\7?\2\2\u01caL\3\2\2\2\u01cb\u01cc"+
"\2\2\2\u01cf\u01d0\7-\2\2\u01d0R\3\2\2\2\u01d1\u01d2\7/\2\2\u01d2T\3\2"+ "\7-\2\2\u01cc\u01cd\7-\2\2\u01cdN\3\2\2\2\u01ce\u01cf\7/\2\2\u01cf\u01d0"+
"\2\2\u01d3\u01d4\7\u0080\2\2\u01d4V\3\2\2\2\u01d5\u01d6\7,\2\2\u01d6\u01d7"+ "\7/\2\2\u01d0P\3\2\2\2\u01d1\u01d2\7-\2\2\u01d2R\3\2\2\2\u01d3\u01d4\7"+
"\7,\2\2\u01d7X\3\2\2\2\u01d8\u01d9\7,\2\2\u01d9Z\3\2\2\2\u01da\u01db\7"+ "/\2\2\u01d4T\3\2\2\2\u01d5\u01d6\7\u0080\2\2\u01d6V\3\2\2\2\u01d7\u01d8"+
"\61\2\2\u01db\\\3\2\2\2\u01dc\u01dd\7\'\2\2\u01dd^\3\2\2\2\u01de\u01df"+ "\7,\2\2\u01d8\u01d9\7,\2\2\u01d9X\3\2\2\2\u01da\u01db\7,\2\2\u01dbZ\3"+
"\7>\2\2\u01df\u01e0\7>\2\2\u01e0`\3\2\2\2\u01e1\u01e2\7@\2\2\u01e2\u01e3"+ "\2\2\2\u01dc\u01dd\7\61\2\2\u01dd\\\3\2\2\2\u01de\u01df\7\'\2\2\u01df"+
"\7@\2\2\u01e3b\3\2\2\2\u01e4\u01e5\7>\2\2\u01e5d\3\2\2\2\u01e6\u01e7\7"+ "^\3\2\2\2\u01e0\u01e1\7>\2\2\u01e1\u01e2\7>\2\2\u01e2`\3\2\2\2\u01e3\u01e4"+
"@\2\2\u01e7f\3\2\2\2\u01e8\u01e9\7>\2\2\u01e9\u01ea\7?\2\2\u01eah\3\2"+ "\7@\2\2\u01e4\u01e5\7@\2\2\u01e5b\3\2\2\2\u01e6\u01e7\7>\2\2\u01e7d\3"+
"\2\2\u01eb\u01ec\7@\2\2\u01ec\u01ed\7?\2\2\u01edj\3\2\2\2\u01ee\u01ef"+ "\2\2\2\u01e8\u01e9\7@\2\2\u01e9f\3\2\2\2\u01ea\u01eb\7>\2\2\u01eb\u01ec"+
"\7?\2\2\u01ef\u01f0\7?\2\2\u01f0l\3\2\2\2\u01f1\u01f2\7#\2\2\u01f2\u01f3"+ "\7?\2\2\u01ech\3\2\2\2\u01ed\u01ee\7@\2\2\u01ee\u01ef\7?\2\2\u01efj\3"+
"\7?\2\2\u01f3n\3\2\2\2\u01f4\u01f5\7`\2\2\u01f5p\3\2\2\2\u01f6\u01f7\7"+ "\2\2\2\u01f0\u01f1\7?\2\2\u01f1\u01f2\7?\2\2\u01f2l\3\2\2\2\u01f3\u01f4"+
"~\2\2\u01f7r\3\2\2\2\u01f8\u01f9\7v\2\2\u01f9\u01fa\7q\2\2\u01fat\3\2"+ "\7#\2\2\u01f4\u01f5\7?\2\2\u01f5n\3\2\2\2\u01f6\u01f7\7`\2\2\u01f7p\3"+
"\2\2\u01fb\u01fc\7u\2\2\u01fc\u01fd\7v\2\2\u01fd\u01fe\7g\2\2\u01fe\u01ff"+ "\2\2\2\u01f8\u01f9\7~\2\2\u01f9r\3\2\2\2\u01fa\u01fb\7v\2\2\u01fb\u01fc"+
"\7r\2\2\u01ffv\3\2\2\2\u0200\u0201\7c\2\2\u0201\u0202\7p\2\2\u0202\u0203"+ "\7q\2\2\u01fct\3\2\2\2\u01fd\u01fe\7u\2\2\u01fe\u01ff\7v\2\2\u01ff\u0200"+
"\7f\2\2\u0203x\3\2\2\2\u0204\u0205\7q\2\2\u0205\u0206\7t\2\2\u0206z\3"+ "\7g\2\2\u0200\u0201\7r\2\2\u0201v\3\2\2\2\u0202\u0203\7c\2\2\u0203\u0204"+
"\2\2\2\u0207\u0208\7z\2\2\u0208\u0209\7q\2\2\u0209\u020a\7t\2\2\u020a"+ "\7p\2\2\u0204\u0205\7f\2\2\u0205x\3\2\2\2\u0206\u0207\7q\2\2\u0207\u0208"+
"|\3\2\2\2\u020b\u020c\7p\2\2\u020c\u020d\7q\2\2\u020d\u020e\7v\2\2\u020e"+ "\7t\2\2\u0208z\3\2\2\2\u0209\u020a\7z\2\2\u020a\u020b\7q\2\2\u020b\u020c"+
"~\3\2\2\2\u020f\u0210\7*\2\2\u0210\u0080\3\2\2\2\u0211\u0212\7+\2\2\u0212"+ "\7t\2\2\u020c|\3\2\2\2\u020d\u020e\7p\2\2\u020e\u020f\7q\2\2\u020f\u0210"+
"\u0082\3\2\2\2\u0213\u0214\7c\2\2\u0214\u0215\7u\2\2\u0215\u0084\3\2\2"+ "\7v\2\2\u0210~\3\2\2\2\u0211\u0212\7*\2\2\u0212\u0080\3\2\2\2\u0213\u0214"+
"\2\u0216\u0217\7B\2\2\u0217\u0086\3\2\2\2\u0218\u0219\7t\2\2\u0219\u021a"+ "\7+\2\2\u0214\u0082\3\2\2\2\u0215\u0216\7c\2\2\u0216\u0217\7u\2\2\u0217"+
"\7g\2\2\u021a\u021b\7v\2\2\u021b\u021c\7w\2\2\u021c\u021d\7t\2\2\u021d"+ "\u0084\3\2\2\2\u0218\u0219\7B\2\2\u0219\u0086\3\2\2\2\u021a\u021b\7t\2"+
"\u021e\7p\2\2\u021e\u0088\3\2\2\2\u021f\u0220\7d\2\2\u0220\u0221\7t\2"+ "\2\u021b\u021c\7g\2\2\u021c\u021d\7v\2\2\u021d\u021e\7w\2\2\u021e\u021f"+
"\2\u0221\u0222\7g\2\2\u0222\u0223\7c\2\2\u0223\u0224\7m\2\2\u0224\u008a"+ "\7t\2\2\u021f\u0220\7p\2\2\u0220\u0088\3\2\2\2\u0221\u0222\7d\2\2\u0222"+
"\3\2\2\2\u0225\u0226\7e\2\2\u0226\u0227\7q\2\2\u0227\u0228\7p\2\2\u0228"+ "\u0223\7t\2\2\u0223\u0224\7g\2\2\u0224\u0225\7c\2\2\u0225\u0226\7m\2\2"+
"\u0229\7v\2\2\u0229\u022a\7k\2\2\u022a\u022b\7p\2\2\u022b\u022c\7w\2\2"+ "\u0226\u008a\3\2\2\2\u0227\u0228\7e\2\2\u0228\u0229\7q\2\2\u0229\u022a"+
"\u022c\u022d\7g\2\2\u022d\u008c\3\2\2\2\u022e\u022f\7\60\2\2\u022f\u008e"+ "\7p\2\2\u022a\u022b\7v\2\2\u022b\u022c\7k\2\2\u022c\u022d\7p\2\2\u022d"+
"\3\2\2\2\u0230\u0231\7C\2\2\u0231\u0090\3\2\2\2\u0232\u0233\7Z\2\2\u0233"+ "\u022e\7w\2\2\u022e\u022f\7g\2\2\u022f\u008c\3\2\2\2\u0230\u0231\7\60"+
"\u0092\3\2\2\2\u0234\u0235\7[\2\2\u0235\u0094\3\2\2\2\u0236\u0237\7C\2"+ "\2\2\u0231\u008e\3\2\2\2\u0232\u0233\7C\2\2\u0233\u0090\3\2\2\2\u0234"+
"\2\u0237\u0238\7Z\2\2\u0238\u0096\3\2\2\2\u0239\u023a\7C\2\2\u023a\u023b"+ "\u0235\7Z\2\2\u0235\u0092\3\2\2\2\u0236\u0237\7[\2\2\u0237\u0094\3\2\2"+
"\7[\2\2\u023b\u0098\3\2\2\2\u023c\u023d\7Z\2\2\u023d\u023e\7[\2\2\u023e"+ "\2\u0238\u0239\7C\2\2\u0239\u023a\7Z\2\2\u023a\u0096\3\2\2\2\u023b\u023c"+
"\u009a\3\2\2\2\u023f\u0240\7R\2\2\u0240\u0241\7e\2\2\u0241\u009c\3\2\2"+ "\7C\2\2\u023c\u023d\7[\2\2\u023d\u0098\3\2\2\2\u023e\u023f\7Z\2\2\u023f"+
"\2\u0242\u0243\7R\2\2\u0243\u0244\7|\2\2\u0244\u009e\3\2\2\2\u0245\u0246"+ "\u0240\7[\2\2\u0240\u009a\3\2\2\2\u0241\u0242\7R\2\2\u0242\u0243\7e\2"+
"\7R\2\2\u0246\u0247\7p\2\2\u0247\u00a0\3\2\2\2\u0248\u0249\7R\2\2\u0249"+ "\2\u0243\u009c\3\2\2\2\u0244\u0245\7R\2\2\u0245\u0246\7|\2\2\u0246\u009e"+
"\u024a\7x\2\2\u024a\u00a2\3\2\2\2\u024b\u024c\7\60\2\2\u024c\u024d\7y"+ "\3\2\2\2\u0247\u0248\7R\2\2\u0248\u0249\7p\2\2\u0249\u00a0\3\2\2\2\u024a"+
"\2\2\u024d\u00a4\3\2\2\2\u024e\u024f\7v\2\2\u024f\u0250\7t\2\2\u0250\u0251"+ "\u024b\7R\2\2\u024b\u024c\7x\2\2\u024c\u00a2\3\2\2\2\u024d\u024e\7\60"+
"\7w\2\2\u0251\u0252\7g\2\2\u0252\u00a6\3\2\2\2\u0253\u0254\7h\2\2\u0254"+ "\2\2\u024e\u024f\7y\2\2\u024f\u00a4\3\2\2\2\u0250\u0251\7v\2\2\u0251\u0252"+
"\u0255\7c\2\2\u0255\u0256\7n\2\2\u0256\u0257\7u\2\2\u0257\u0258\7g\2\2"+ "\7t\2\2\u0252\u0253\7w\2\2\u0253\u0254\7g\2\2\u0254\u00a6\3\2\2\2\u0255"+
"\u0258\u00a8\3\2\2\2\u0259\u025a\7\'\2\2\u025a\u025b\7c\2\2\u025b\u025c"+ "\u0256\7h\2\2\u0256\u0257\7c\2\2\u0257\u0258\7n\2\2\u0258\u0259\7u\2\2"+
"\7u\2\2\u025c\u025d\7o\2\2\u025d\u00aa\3\2\2\2\u025e\u025f\7u\2\2\u025f"+ "\u0259\u025a\7g\2\2\u025a\u00a8\3\2\2\2\u025b\u025c\7\'\2\2\u025c\u025d"+
"\u0260\7w\2\2\u0260\u0261\7d\2\2\u0261\u00ac\3\2\2\2\u0262\u0263\7/\2"+ "\7c\2\2\u025d\u025e\7u\2\2\u025e\u025f\7o\2\2\u025f\u00aa\3\2\2\2\u0260"+
"\2\u0263\u0264\7@\2\2\u0264\u00ae\3\2\2\2\u0265\u0266\7c\2\2\u0266\u0267"+ "\u0261\7u\2\2\u0261\u0262\7w\2\2\u0262\u0263\7d\2\2\u0263\u00ac\3\2\2"+
"\7u\2\2\u0267\u0268\7o\2\2\u0268\u0269\7u\2\2\u0269\u026a\7w\2\2\u026a"+ "\2\u0264\u0265\7/\2\2\u0265\u0266\7@\2\2\u0266\u00ae\3\2\2\2\u0267\u0268"+
"\u026b\7d\2\2\u026b\u00b0\3\2\2\2\u026c\u026d\7u\2\2\u026d\u026e\7v\2"+ "\7c\2\2\u0268\u0269\7u\2\2\u0269\u026a\7o\2\2\u026a\u026b\7u\2\2\u026b"+
"\2\u026e\u026f\7c\2\2\u026f\u0270\7e\2\2\u0270\u0271\7m\2\2\u0271\u00b2"+ "\u026c\7w\2\2\u026c\u026d\7d\2\2\u026d\u00b0\3\2\2\2\u026e\u026f\7t\2"+
"\3\2\2\2\u0272\u0273\7e\2\2\u0273\u0274\7n\2\2\u0274\u0275\7q\2\2\u0275"+ "\2\u026f\u0270\7q\2\2\u0270\u0271\7o\2\2\u0271\u0272\7u\2\2\u0272\u0273"+
"\u0276\7d\2\2\u0276\u0277\7d\2\2\u0277\u0278\7g\2\2\u0278\u0279\7t\2\2"+ "\7w\2\2\u0273\u0274\7d\2\2\u0274\u00b2\3\2\2\2\u0275\u0276\7u\2\2\u0276"+
"\u0279\u027a\7u\2\2\u027a\u00b4\3\2\2\2\u027b\u027c\7k\2\2\u027c\u027d"+ "\u0277\7v\2\2\u0277\u0278\7c\2\2\u0278\u0279\7e\2\2\u0279\u027a\7m\2\2"+
"\7h\2\2\u027d\u00b6\3\2\2\2\u027e\u027f\7g\2\2\u027f\u0280\7n\2\2\u0280"+ "\u027a\u00b4\3\2\2\2\u027b\u027c\7e\2\2\u027c\u027d\7n\2\2\u027d\u027e"+
"\u0281\7u\2\2\u0281\u0282\7g\2\2\u0282\u00b8\3\2\2\2\u0283\u0284\7k\2"+ "\7q\2\2\u027e\u027f\7d\2\2\u027f\u0280\7d\2\2\u0280\u0281\7g\2\2\u0281"+
"\2\u0284\u0285\7h\2\2\u0285\u0286\7a\2\2\u0286\u0287\7e\2\2\u0287\u0288"+ "\u0282\7t\2\2\u0282\u0283\7u\2\2\u0283\u00b6\3\2\2\2\u0284\u0285\7k\2"+
"\7u\2\2\u0288\u00ba\3\2\2\2\u0289\u028a\7k\2\2\u028a\u028b\7h\2\2\u028b"+ "\2\u0285\u0286\7h\2\2\u0286\u00b8\3\2\2\2\u0287\u0288\7g\2\2\u0288\u0289"+
"\u028c\7a\2\2\u028c\u028d\7e\2\2\u028d\u028e\7e\2\2\u028e\u00bc\3\2\2"+ "\7n\2\2\u0289\u028a\7u\2\2\u028a\u028b\7g\2\2\u028b\u00ba\3\2\2\2\u028c"+
"\2\u028f\u0290\7k\2\2\u0290\u0291\7h\2\2\u0291\u0292\7a\2\2\u0292\u0293"+ "\u028d\7k\2\2\u028d\u028e\7h\2\2\u028e\u028f\7a\2\2\u028f\u0290\7e\2\2"+
"\7g\2\2\u0293\u0294\7s\2\2\u0294\u00be\3\2\2\2\u0295\u0296\7k\2\2\u0296"+ "\u0290\u0291\7u\2\2\u0291\u00bc\3\2\2\2\u0292\u0293\7k\2\2\u0293\u0294"+
"\u0297\7h\2\2\u0297\u0298\7a\2\2\u0298\u0299\7|\2\2\u0299\u00c0\3\2\2"+ "\7h\2\2\u0294\u0295\7a\2\2\u0295\u0296\7e\2\2\u0296\u0297\7e\2\2\u0297"+
"\2\u029a\u029b\7k\2\2\u029b\u029c\7h\2\2\u029c\u029d\7a\2\2\u029d\u029e"+ "\u00be\3\2\2\2\u0298\u0299\7k\2\2\u0299\u029a\7h\2\2\u029a\u029b\7a\2"+
"\7p\2\2\u029e\u029f\7g\2\2\u029f\u00c2\3\2\2\2\u02a0\u02a1\7k\2\2\u02a1"+ "\2\u029b\u029c\7g\2\2\u029c\u029d\7s\2\2\u029d\u00c0\3\2\2\2\u029e\u029f"+
"\u02a2\7h\2\2\u02a2\u02a3\7a\2\2\u02a3\u02a4\7p\2\2\u02a4\u02a5\7|\2\2"+ "\7k\2\2\u029f\u02a0\7h\2\2\u02a0\u02a1\7a\2\2\u02a1\u02a2\7|\2\2\u02a2"+
"\u02a5\u00c4\3\2\2\2\u02a6\u02a7\7k\2\2\u02a7\u02a8\7h\2\2\u02a8\u02a9"+ "\u00c2\3\2\2\2\u02a3\u02a4\7k\2\2\u02a4\u02a5\7h\2\2\u02a5\u02a6\7a\2"+
"\7a\2\2\u02a9\u02aa\7r\2\2\u02aa\u02ab\7n\2\2\u02ab\u00c6\3\2\2\2\u02ac"+ "\2\u02a6\u02a7\7p\2\2\u02a7\u02a8\7g\2\2\u02a8\u00c4\3\2\2\2\u02a9\u02aa"+
"\u02ad\7k\2\2\u02ad\u02ae\7h\2\2\u02ae\u02af\7a\2\2\u02af\u02b0\7r\2\2"+ "\7k\2\2\u02aa\u02ab\7h\2\2\u02ab\u02ac\7a\2\2\u02ac\u02ad\7p\2\2\u02ad"+
"\u02b0\u02b1\7q\2\2\u02b1\u02b2\7u\2\2\u02b2\u00c8\3\2\2\2\u02b3\u02b4"+ "\u02ae\7|\2\2\u02ae\u00c6\3\2\2\2\u02af\u02b0\7k\2\2\u02b0\u02b1\7h\2"+
"\7k\2\2\u02b4\u02b5\7h\2\2\u02b5\u02b6\7a\2\2\u02b6\u02b7\7o\2\2\u02b7"+ "\2\u02b1\u02b2\7a\2\2\u02b2\u02b3\7r\2\2\u02b3\u02b4\7n\2\2\u02b4\u00c8"+
"\u02b8\7k\2\2\u02b8\u00ca\3\2\2\2\u02b9\u02ba\7k\2\2\u02ba\u02bb\7h\2"+ "\3\2\2\2\u02b5\u02b6\7k\2\2\u02b6\u02b7\7h\2\2\u02b7\u02b8\7a\2\2\u02b8"+
"\2\u02bb\u02bc\7a\2\2\u02bc\u02bd\7p\2\2\u02bd\u02be\7g\2\2\u02be\u02bf"+ "\u02b9\7r\2\2\u02b9\u02ba\7q\2\2\u02ba\u02bb\7u\2\2\u02bb\u00ca\3\2\2"+
"\7i\2\2\u02bf\u00cc\3\2\2\2\u02c0\u02c1\7k\2\2\u02c1\u02c2\7h\2\2\u02c2"+ "\2\u02bc\u02bd\7k\2\2\u02bd\u02be\7h\2\2\u02be\u02bf\7a\2\2\u02bf\u02c0"+
"\u02c3\7a\2\2\u02c3\u02c4\7x\2\2\u02c4\u02c5\7u\2\2\u02c5\u00ce\3\2\2"+ "\7o\2\2\u02c0\u02c1\7k\2\2\u02c1\u00cc\3\2\2\2\u02c2\u02c3\7k\2\2\u02c3"+
"\2\u02c6\u02c7\7k\2\2\u02c7\u02c8\7h\2\2\u02c8\u02c9\7a\2\2\u02c9\u02ca"+ "\u02c4\7h\2\2\u02c4\u02c5\7a\2\2\u02c5\u02c6\7p\2\2\u02c6\u02c7\7g\2\2"+
"\7x\2\2\u02ca\u02cb\7e\2\2\u02cb\u00d0\3\2\2\2\u02cc\u02cd\7h\2\2\u02cd"+ "\u02c7\u02c8\7i\2\2\u02c8\u00ce\3\2\2\2\u02c9\u02ca\7k\2\2\u02ca\u02cb"+
"\u02ce\7q\2\2\u02ce\u02cf\7t\2\2\u02cf\u00d2\3\2\2\2\u02d0\u02d1\7k\2"+ "\7h\2\2\u02cb\u02cc\7a\2\2\u02cc\u02cd\7x\2\2\u02cd\u02ce\7u\2\2\u02ce"+
"\2\u02d1\u02d2\7p\2\2\u02d2\u00d4\3\2\2\2\u02d3\u02d4\7y\2\2\u02d4\u02d5"+ "\u00d0\3\2\2\2\u02cf\u02d0\7k\2\2\u02d0\u02d1\7h\2\2\u02d1\u02d2\7a\2"+
"\7j\2\2\u02d5\u02d6\7k\2\2\u02d6\u02d7\7n\2\2\u02d7\u02d8\7g\2\2\u02d8"+ "\2\u02d2\u02d3\7x\2\2\u02d3\u02d4\7e\2\2\u02d4\u00d2\3\2\2\2\u02d5\u02d6"+
"\u00d6\3\2\2\2\u02d9\u02da\7t\2\2\u02da\u02db\7g\2\2\u02db\u02dc\7r\2"+ "\7h\2\2\u02d6\u02d7\7q\2\2\u02d7\u02d8\7t\2\2\u02d8\u00d4\3\2\2\2\u02d9"+
"\2\u02dc\u02dd\7g\2\2\u02dd\u02de\7c\2\2\u02de\u02df\7v\2\2\u02df\u00d8"+ "\u02da\7k\2\2\u02da\u02db\7p\2\2\u02db\u00d6\3\2\2\2\u02dc\u02dd\7y\2"+
"\3\2\2\2\u02e0\u02e1\7w\2\2\u02e1\u02e2\7p\2\2\u02e2\u02e3\7v\2\2\u02e3"+ "\2\u02dd\u02de\7j\2\2\u02de\u02df\7k\2\2\u02df\u02e0\7n\2\2\u02e0\u02e1"+
"\u02e4\7k\2\2\u02e4\u02e5\7n\2\2\u02e5\u00da\3\2\2\2\u02e6\u02e7\7y\2"+ "\7g\2\2\u02e1\u00d8\3\2\2\2\u02e2\u02e3\7t\2\2\u02e3\u02e4\7g\2\2\u02e4"+
"\2\u02e7\u02e8\7j\2\2\u02e8\u02e9\7g\2\2\u02e9\u02ea\7p\2\2\u02ea\u00dc"+ "\u02e5\7r\2\2\u02e5\u02e6\7g\2\2\u02e6\u02e7\7c\2\2\u02e7\u02e8\7v\2\2"+
"\3\2\2\2\u02eb\u02ef\t\2\2\2\u02ec\u02ee\t\3\2\2\u02ed\u02ec\3\2\2\2\u02ee"+ "\u02e8\u00da\3\2\2\2\u02e9\u02ea\7w\2\2\u02ea\u02eb\7p\2\2\u02eb\u02ec"+
"\u02f1\3\2\2\2\u02ef\u02ed\3\2\2\2\u02ef\u02f0\3\2\2\2\u02f0\u02f2\3\2"+ "\7v\2\2\u02ec\u02ed\7k\2\2\u02ed\u02ee\7n\2\2\u02ee\u00dc\3\2\2\2\u02ef"+
"\2\2\u02f1\u02ef\3\2\2\2\u02f2\u02f3\5\u00dfp\2\u02f3\u02f4\3\2\2\2\u02f4"+ "\u02f0\7y\2\2\u02f0\u02f1\7j\2\2\u02f1\u02f2\7g\2\2\u02f2\u02f3\7p\2\2"+
"\u02f5\bo\2\2\u02f5\u00de\3\2\2\2\u02f6\u02fa\7=\2\2\u02f7\u02f9\n\2\2"+ "\u02f3\u00de\3\2\2\2\u02f4\u02f8\t\2\2\2\u02f5\u02f7\t\3\2\2\u02f6\u02f5"+
"\2\u02f8\u02f7\3\2\2\2\u02f9\u02fc\3\2\2\2\u02fa\u02f8\3\2\2\2\u02fa\u02fb"+ "\3\2\2\2\u02f7\u02fa\3\2\2\2\u02f8\u02f6\3\2\2\2\u02f8\u02f9\3\2\2\2\u02f9"+
"\3\2\2\2\u02fb\u02fd\3\2\2\2\u02fc\u02fa\3\2\2\2\u02fd\u02fe\bp\2\2\u02fe"+ "\u02fb\3\2\2\2\u02fa\u02f8\3\2\2\2\u02fb\u02fc\5\u00e1q\2\u02fc\u02fd"+
"\u00e0\3\2\2\2\u02ff\u0300\t\3\2\2\u0300\u0301\3\2\2\2\u0301\u0302\bq"+ "\3\2\2\2\u02fd\u02fe\bp\2\2\u02fe\u00e0\3\2\2\2\u02ff\u0303\7=\2\2\u0300"+
"\3\2\u0302\u00e2\3\2\2\2\u0303\u0305\t\2\2\2\u0304\u0303\3\2\2\2\u0305"+ "\u0302\n\2\2\2\u0301\u0300\3\2\2\2\u0302\u0305\3\2\2\2\u0303\u0301\3\2"+
"\u0306\3\2\2\2\u0306\u0304\3\2\2\2\u0306\u0307\3\2\2\2\u0307\u00e4\3\2"+ "\2\2\u0303\u0304\3\2\2\2\u0304\u0306\3\2\2\2\u0305\u0303\3\2\2\2\u0306"+
"\2\2\u0308\u0309\7x\2\2\u0309\u030a\7q\2\2\u030a\u030b\7k\2\2\u030b\u030c"+ "\u0307\bq\2\2\u0307\u00e2\3\2\2\2\u0308\u0309\t\3\2\2\u0309\u030a\3\2"+
"\7f\2\2\u030c\u00e6\3\2\2\2\u030d\u0311\t\4\2\2\u030e\u0310\t\5\2\2\u030f"+ "\2\2\u030a\u030b\br\3\2\u030b\u00e4\3\2\2\2\u030c\u030e\t\2\2\2\u030d"+
"\u030e\3\2\2\2\u0310\u0313\3\2\2\2\u0311\u030f\3\2\2\2\u0311\u0312\3\2"+ "\u030c\3\2\2\2\u030e\u030f\3\2\2\2\u030f\u030d\3\2\2\2\u030f\u0310\3\2"+
"\2\2\u0312\u00e8\3\2\2\2\u0313\u0311\3\2\2\2\u0314\u031c\4\62;\2\u0315"+ "\2\2\u0310\u00e6\3\2\2\2\u0311\u0312\7x\2\2\u0312\u0313\7q\2\2\u0313\u0314"+
"\u0317\4\63;\2\u0316\u0318\4\62;\2\u0317\u0316\3\2\2\2\u0318\u0319\3\2"+ "\7k\2\2\u0314\u0315\7f\2\2\u0315\u00e8\3\2\2\2\u0316\u031a\t\4\2\2\u0317"+
"\2\2\u0319\u0317\3\2\2\2\u0319\u031a\3\2\2\2\u031a\u031c\3\2\2\2\u031b"+ "\u0319\t\5\2\2\u0318\u0317\3\2\2\2\u0319\u031c\3\2\2\2\u031a\u0318\3\2"+
"\u0314\3\2\2\2\u031b\u0315\3\2\2\2\u031c\u00ea\3\2\2\2\u031d\u031f\7&"+ "\2\2\u031a\u031b\3\2\2\2\u031b\u00ea\3\2\2\2\u031c\u031a\3\2\2\2\u031d"+
"\2\2\u031e\u0320\t\6\2\2\u031f\u031e\3\2\2\2\u0320\u0321\3\2\2\2\u0321"+ "\u0325\4\62;\2\u031e\u0320\4\63;\2\u031f\u0321\4\62;\2\u0320\u031f\3\2"+
"\u031f\3\2\2\2\u0321\u0322\3\2\2\2\u0322\u00ec\3\2\2\2\u0323\u0325\7\'"+ "\2\2\u0321\u0322\3\2\2\2\u0322\u0320\3\2\2\2\u0322\u0323\3\2\2\2\u0323"+
"\2\2\u0324\u0326\4\62\63\2\u0325\u0324\3\2\2\2\u0326\u0327\3\2\2\2\u0327"+ "\u0325\3\2\2\2\u0324\u031d\3\2\2\2\u0324\u031e\3\2\2\2\u0325\u00ec\3\2"+
"\u0325\3\2\2\2\u0327\u0328\3\2\2\2\u0328\u00ee\3\2\2\2\u0329\u032a\7("+ "\2\2\u0326\u0328\7&\2\2\u0327\u0329\t\6\2\2\u0328\u0327\3\2\2\2\u0329"+
"\2\2\u032a\u00f0\3\2\2\2\u032b\u0331\5\u00f3z\2\u032c\u032e\t\7\2\2\u032d"+ "\u032a\3\2\2\2\u032a\u0328\3\2\2\2\u032a\u032b\3\2\2\2\u032b\u00ee\3\2"+
"\u032f\t\b\2\2\u032e\u032d\3\2\2\2\u032e\u032f\3\2\2\2\u032f\u0330\3\2"+ "\2\2\u032c\u032e\7\'\2\2\u032d\u032f\4\62\63\2\u032e\u032d\3\2\2\2\u032f"+
"\2\2\u0330\u0332\5\u00f3z\2\u0331\u032c\3\2\2\2\u0331\u0332\3\2\2\2\u0332"+ "\u0330\3\2\2\2\u0330\u032e\3\2\2\2\u0330\u0331\3\2\2\2\u0331\u00f0\3\2"+
"\u00f2\3\2\2\2\u0333\u0335\4\62;\2\u0334\u0333\3\2\2\2\u0335\u0336\3\2"+ "\2\2\u0332\u0333\7(\2\2\u0333\u00f2\3\2\2\2\u0334\u033a\5\u00f5{\2\u0335"+
"\2\2\u0336\u0334\3\2\2\2\u0336\u0337\3\2\2\2\u0337\u033e\3\2\2\2\u0338"+ "\u0337\t\7\2\2\u0336\u0338\t\b\2\2\u0337\u0336\3\2\2\2\u0337\u0338\3\2"+
"\u033a\7\60\2\2\u0339\u033b\4\62;\2\u033a\u0339\3\2\2\2\u033b\u033c\3"+ "\2\2\u0338\u0339\3\2\2\2\u0339\u033b\5\u00f5{\2\u033a\u0335\3\2\2\2\u033a"+
"\2\2\2\u033c\u033a\3\2\2\2\u033c\u033d\3\2\2\2\u033d\u033f\3\2\2\2\u033e"+ "\u033b\3\2\2\2\u033b\u00f4\3\2\2\2\u033c\u033e\4\62;\2\u033d\u033c\3\2"+
"\u0338\3\2\2\2\u033e\u033f\3\2\2\2\u033f\u00f4\3\2\2\2\u0340\u0341\7^"+ "\2\2\u033e\u033f\3\2\2\2\u033f\u033d\3\2\2\2\u033f\u0340\3\2\2\2\u0340"+
"\2\2\u0341\u0345\13\2\2\2\u0342\u0343\7^\2\2\u0343\u0345\5\u00e3r\2\u0344"+ "\u0347\3\2\2\2\u0341\u0343\7\60\2\2\u0342\u0344\4\62;\2\u0343\u0342\3"+
"\u0340\3\2\2\2\u0344\u0342\3\2\2\2\u0345\u00f6\3\2\2\2\u0346\u034b\7$"+ "\2\2\2\u0344\u0345\3\2\2\2\u0345\u0343\3\2\2\2\u0345\u0346\3\2\2\2\u0346"+
"\2\2\u0347\u034a\5\u00f5{\2\u0348\u034a\n\t\2\2\u0349\u0347\3\2\2\2\u0349"+ "\u0348\3\2\2\2\u0347\u0341\3\2\2\2\u0347\u0348\3\2\2\2\u0348\u00f6\3\2"+
"\u0348\3\2\2\2\u034a\u034d\3\2\2\2\u034b\u0349\3\2\2\2\u034b\u034c\3\2"+ "\2\2\u0349\u034a\7^\2\2\u034a\u034e\13\2\2\2\u034b\u034c\7^\2\2\u034c"+
"\2\2\u034c\u034e\3\2\2\2\u034d\u034b\3\2\2\2\u034e\u034f\7$\2\2\u034f"+ "\u034e\5\u00e5s\2\u034d\u0349\3\2\2\2\u034d\u034b\3\2\2\2\u034e\u00f8"+
"\u0350\b|\4\2\u0350\u00f8\3\2\2\2\u0351\u0352\7}\2\2\u0352\u0353\7}\2"+ "\3\2\2\2\u034f\u0354\7$\2\2\u0350\u0353\5\u00f7|\2\u0351\u0353\n\t\2\2"+
"\2\u0353\u0355\3\2\2\2\u0354\u0356\13\2\2\2\u0355\u0354\3\2\2\2\u0356"+ "\u0352\u0350\3\2\2\2\u0352\u0351\3\2\2\2\u0353\u0356\3\2\2\2\u0354\u0352"+
"\u0357\3\2\2\2\u0357\u0358\3\2\2\2\u0357\u0355\3\2\2\2\u0358\u0359\3\2"+ "\3\2\2\2\u0354\u0355\3\2\2\2\u0355\u0357\3\2\2\2\u0356\u0354\3\2\2\2\u0357"+
"\2\2\u0359\u035a\7\177\2\2\u035a\u035b\7\177\2\2\u035b\u035c\3\2\2\2\u035c"+ "\u0358\7$\2\2\u0358\u0359\b}\4\2\u0359\u00fa\3\2\2\2\u035a\u035b\7}\2"+
"\u035d\b}\5\2\u035d\u00fa\3\2\2\2\u035e\u0361\7)\2\2\u035f\u0362\5\u00f5"+ "\2\u035b\u035c\7}\2\2\u035c\u035e\3\2\2\2\u035d\u035f\13\2\2\2\u035e\u035d"+
"{\2\u0360\u0362\n\t\2\2\u0361\u035f\3\2\2\2\u0361\u0360\3\2\2\2\u0362"+ "\3\2\2\2\u035f\u0360\3\2\2\2\u0360\u0361\3\2\2\2\u0360\u035e\3\2\2\2\u0361"+
"\u0363\3\2\2\2\u0363\u0364\7)\2\2\u0364\u0365\b~\6\2\u0365\u00fc\3\2\2"+ "\u0362\3\2\2\2\u0362\u0363\7\177\2\2\u0363\u0364\7\177\2\2\u0364\u0365"+
"\2\u0366\u0367\7B\2\2\u0367\u0368\7|\2\2\u0368\u0369\7r\2\2\u0369\u00fe"+ "\3\2\2\2\u0365\u0366\b~\5\2\u0366\u00fc\3\2\2\2\u0367\u036a\7)\2\2\u0368"+
"\3\2\2\2\u036a\u036b\7]\2\2\u036b\u036c\7_\2\2\u036c\u0100\3\2\2\2\26"+ "\u036b\5\u00f7|\2\u0369\u036b\n\t\2\2\u036a\u0368\3\2\2\2\u036a\u0369"+
"\2\u02ef\u02fa\u0306\u0311\u0319\u031b\u031f\u0321\u0327\u032e\u0331\u0336"+ "\3\2\2\2\u036b\u036c\3\2\2\2\u036c\u036d\7)\2\2\u036d\u036e\b\177\6\2"+
"\u033c\u033e\u0344\u0349\u034b\u0357\u0361\7\2\3\2\b\2\2\3|\2\3}\3\3~"+ "\u036e\u00fe\3\2\2\2\u036f\u0370\7B\2\2\u0370\u0371\7|\2\2\u0371\u0372"+
"\4"; "\7r\2\2\u0372\u0100\3\2\2\2\u0373\u0374\7]\2\2\u0374\u0375\7_\2\2\u0375"+
"\u0102\3\2\2\2\26\2\u02f8\u0303\u030f\u031a\u0322\u0324\u0328\u032a\u0330"+
"\u0337\u033a\u033f\u0345\u0347\u034d\u0352\u0354\u0360\u036a\7\2\3\2\b"+
"\2\2\3}\2\3~\3\3\177\4";
public static final ATN _ATN = public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray()); new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static { static {

File diff suppressed because it is too large Load Diff