Compare commits

...

59 Commits
v6.3 ... v6.4

Author SHA1 Message Date
4cae2c56ec implemented last remaining codegen for word-byte division and remainders. 2021-03-25 22:03:36 +01:00
d840975054 remove unreached error checks 2021-03-25 21:47:05 +01:00
1b14da6c03 compiler warning instead of crash when attempting to assign invalid array value to other array 2021-03-24 22:01:22 +01:00
292640b17a asmgen: string values cannot be typecasted 2021-03-24 21:49:33 +01:00
112a7b09f2 added codegen for expression that needs the status-flag register result as a value on the stack 2021-03-24 21:42:27 +01:00
863ec9ce8a Merge pull request #26 from Elektron72/vim-syntax
Add support for built-in functions to Vim syntax file (and other fixes)
2021-03-24 20:50:53 +01:00
2eb346a205 Add support for built-ins to Vim syntax file
This commit adds support for highlighting built-in functions and
variables to the Vim syntax file.
2021-03-23 19:53:20 -04:00
8092355acb Add syntax sync to Vim syntax file
This will make the highlighting slightly slower, but will fix issues
with assembly not being highlighted properly.
2021-03-23 19:41:34 -04:00
e7ef2ed31b todo 2021-03-23 23:48:53 +01:00
af4de6d2fc replacing complex array indexer expressions moved to BeforeAsmGeneration + use cx16 virtualregister instead of adding temp variables for this 2021-03-23 23:44:14 +01:00
69f73dd779 Add void operator to Vim syntax file 2021-03-23 18:12:52 -04:00
9706b46012 credits 2021-03-23 02:50:16 +01:00
6d75dd3bb8 Merge pull request #25 from Elektron72/vim-syntax
Add Vim syntax highlighting file
2021-03-23 01:29:57 +01:00
bd295ffc99 array indexer complexity is now dealt with in the asm-generator only 2021-03-22 19:40:57 +01:00
07ce3e3c9d Add Vim syntax highlighting file
The readme file in syntax-files/Vim/ was also modified to give simple
installation instructions.
2021-03-22 12:13:20 -04:00
cbc3e37a89 stuff 2021-03-22 02:29:59 +01:00
3626828ceb decided 2021-03-22 01:45:19 +01:00
24b77fb5a5 comments. 2021-03-21 21:10:29 +01:00
1505fe686a updated vtui example 2021-03-21 20:40:35 +01:00
0991131fa8 don't stript unused asmsub definitions 2021-03-21 19:55:21 +01:00
2e928bd3c2 fix compiler crash for certain str argument to asm functions 2021-03-21 18:39:39 +01:00
ca868ae19e added cx16.vload() (like the VLOAD basic instruction) 2021-03-20 02:39:53 +01:00
3e286dd14c move test 2021-03-18 19:34:54 +01:00
11247d52b1 fix bugs in word <= and >= comparisons 2021-03-18 19:20:48 +01:00
1dbc902513 fix bugs in uword <= and >= comparisons 2021-03-18 18:41:41 +01:00
330e691b78 wip 2021-03-18 02:43:08 +01:00
6780d4f562 fix bug in uword > comparison 2021-03-18 02:21:21 +01:00
b30b8b7368 fix bug in float < and > comparisons 2021-03-18 01:41:54 +01:00
3df182b8c3 created extensive comparison test suite 2021-03-18 00:50:13 +01:00
7f21d89fea moved test programs to test folder in compiler module 2021-03-17 20:15:16 +01:00
2b267b4ba1 IDE syntax 2021-03-17 19:36:37 +01:00
ef64881528 busy creating extensive comparison test suite 2021-03-17 19:35:22 +01:00
9a6bd760bd fixed issues in uword '>' 2021-03-16 23:40:32 +01:00
00b9766aea fixed issues in word '>' 2021-03-16 23:22:58 +01:00
6381d2b6ac improve word '<', word (u)word '<=' , uword '>=' codegen 2021-03-16 18:15:47 +01:00
d2ab5f230d example TODOs 2021-03-16 01:09:25 +01:00
824b41d457 improve word '>' and '>=' codegen 2021-03-16 00:48:03 +01:00
b5523c7077 don't optimize with inlining too aggressively (code bloat) 2021-03-16 00:33:15 +01:00
eb3594b18c revert to just using comparison expressions in graphics code (we're optimizing these now!) 2021-03-16 00:11:55 +01:00
852d85d010 improve uword '<' and '>' codegen 2021-03-16 00:03:51 +01:00
5e0aef04fe improve (u)byte '>=' codegen 2021-03-15 23:20:16 +01:00
a00c693f93 improve (u)byte '<=' codegen 2021-03-15 23:17:04 +01:00
c943da1448 improve ubyte '<' and '>' codegen 2021-03-15 23:12:52 +01:00
b630fae580 refactor byte '==', '!=', '<' and '>' codegen 2 2021-03-15 23:08:30 +01:00
38e40084f1 refactor byte '==', '!=', '<' and '>' codegen 2021-03-15 22:47:18 +01:00
bf23ad78e6 improve byte '<' and '>' codegen 2021-03-15 22:26:00 +01:00
ded1d19737 improve '==' and '!=' codegen 2021-03-15 19:29:32 +01:00
496a3b0d2c todo 2021-03-15 18:56:25 +01:00
6922333755 add a cmp(x,y) function that returns no value but only sets the status bits based off the comparison (can be used with a conditional jump afterwards) 2021-03-13 15:11:22 +01:00
a00c39e9cf compiler error instead of crash when using functioncall without returnvalue 2021-03-12 19:31:04 +01:00
1c1da8e38e additional optimization to the bresenham line routines 2021-03-10 18:49:40 +01:00
50a306f492 line drawing fixes 2021-03-09 22:11:30 +01:00
6995ee2d17 fix cx16 bresenham line inaccuracy 2021-03-09 22:04:19 +01:00
6c60ea9cac allocate even more c64 zeropage locations for floats 2021-03-09 21:47:36 +01:00
2431ed811a don't remove typecasts in asmsub argument lists 2021-03-09 21:29:48 +01:00
6bd205c02a fix c64 bresenham line inaccuracy 2021-03-09 21:07:55 +01:00
62ec77e148 ver 2021-03-08 23:35:52 +01:00
9120e1de88 fix ubyte/uword to float conversion crashes on Commander X16 2021-03-08 23:21:52 +01:00
60e169bd87 added optimized integer square (x*x) routine 2021-03-08 23:08:47 +01:00
78 changed files with 2899 additions and 3419 deletions

View File

@ -1,5 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="Python" name="Python">
<configuration sdkName="Python 3.9" />
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
@ -14,5 +19,6 @@
<orderEntry type="library" name="unittest-libs" level="project" />
<orderEntry type="library" name="kotlinx-cli-jvm" level="project" />
<orderEntry type="module" module-name="compilerAst" />
<orderEntry type="library" name="Python 3.9 interpreter library" level="application" />
</component>
</module>

View File

@ -428,7 +428,9 @@ var_fac1_greater_f .proc
cmp #1
beq +
lda #0
+ rts
rts
+ lda #1
rts
.pend
var_fac1_greatereq_f .proc

View File

@ -34,36 +34,33 @@ graphics {
sub line(uword @zp x1, ubyte @zp y1, uword @zp x2, ubyte @zp y2) {
; Bresenham algorithm.
; This code special-cases various quadrant loops to allow simple ++ and -- operations.
; TODO there are some slight errors at the first/last pixels in certain slopes...??
if y1>y2 {
; make sure dy is always positive to have only 4 instead of 8 special cases
swap(x1, x2)
swap(y1, y2)
}
word @zp dx = x2-x1 as word
word @zp dy = y2-y1
word @zp dx = (x2 as word)-x1
word @zp dy = (y2 as word)-y1
if dx==0 {
vertical_line(x1, y1, abs(dy)+1 as ubyte)
vertical_line(x1, y1, abs(dy) as ubyte +1)
return
}
if dy==0 {
if x1>x2
x1=x2
horizontal_line(x1, y1, abs(dx)+1 as uword)
horizontal_line(x1, y1, abs(dx) as uword +1)
return
}
; TODO rewrite the rest in optimized assembly
word @zp d = 0
ubyte positive_ix = true
if dx < 0 {
dx = -dx
positive_ix = false
}
dx *= 2
dy *= 2
word @zp dx2 = dx*2
word @zp dy2 = dy*2
internal_plotx = x1
if dx >= dy {
@ -73,10 +70,10 @@ graphics {
if internal_plotx==x2
return
internal_plotx++
d += dy
d += dy2
if d > dx {
y1++
d -= dx
d -= dx2
}
}
} else {
@ -85,10 +82,10 @@ graphics {
if internal_plotx==x2
return
internal_plotx--
d += dy
d += dy2
if d > dx {
y1++
d -= dx
d -= dx2
}
}
}
@ -100,10 +97,10 @@ graphics {
if y1 == y2
return
y1++
d += dx
d += dx2
if d > dy {
internal_plotx++
d -= dy
d -= dy2
}
}
} else {
@ -112,10 +109,10 @@ graphics {
if y1 == y2
return
y1++
d += dx
d += dx2
if d > dy {
internal_plotx--
d -= dy
d -= dy2
}
}
}

View File

@ -202,7 +202,7 @@ romsub $FFAE = UNLSN() clobbers(A) ; command serial
romsub $FFB1 = LISTEN(ubyte device @ A) clobbers(A) ; command serial bus device to LISTEN
romsub $FFB4 = TALK(ubyte device @ A) clobbers(A) ; command serial bus device to TALK
romsub $FFB7 = READST() -> ubyte @ A ; read I/O status word
romsub $FFBA = SETLFS(ubyte logical @ A, ubyte device @ X, ubyte address @ Y) ; set logical file parameters
romsub $FFBA = SETLFS(ubyte logical @ A, ubyte device @ X, ubyte secondary @ Y) ; set logical file parameters
romsub $FFBD = SETNAM(ubyte namelen @ A, str filename @ XY) ; set filename parameters
romsub $FFC0 = OPEN() clobbers(X,Y) -> ubyte @Pc, ubyte @A ; (via 794 ($31A)) open a logical file
romsub $FFC3 = CLOSE(ubyte logical @ A) clobbers(A,X,Y) ; (via 796 ($31C)) close a logical file
@ -211,8 +211,8 @@ romsub $FFC9 = CHKOUT(ubyte logical @ X) clobbers(A,X) ; (via 800 ($320
romsub $FFCC = CLRCHN() clobbers(A,X) ; (via 802 ($322)) restore default devices
romsub $FFCF = CHRIN() clobbers(X, Y) -> ubyte @ A ; (via 804 ($324)) input a character (for keyboard, read a whole line from the screen) A=byte read.
romsub $FFD2 = CHROUT(ubyte char @ A) ; (via 806 ($326)) output a character
romsub $FFD5 = LOAD(ubyte verify @ A, uword address @ XY) -> ubyte @Pc, ubyte @ A, ubyte @ X, ubyte @ Y ; (via 816 ($330)) load from device
romsub $FFD8 = SAVE(ubyte zp_startaddr @ A, uword endaddr @ XY) -> ubyte @ Pc, ubyte @ A ; (via 818 ($332)) save to a device
romsub $FFD5 = LOAD(ubyte verify @ A, uword address @ XY) -> ubyte @Pc, ubyte @ A, uword @ XY ; (via 816 ($330)) load from device
romsub $FFD8 = SAVE(ubyte zp_startaddr @ A, uword endaddr @ XY) -> ubyte @ Pc, ubyte @ A ; (via 818 ($332)) save to a device
romsub $FFDB = SETTIM(ubyte low @ A, ubyte middle @ X, ubyte high @ Y) ; set the software clock
romsub $FFDE = RDTIM() -> ubyte @ A, ubyte @ X, ubyte @ Y ; read the software clock
romsub $FFE1 = STOP() clobbers(X) -> ubyte @ Pz, ubyte @ A ; (via 808 ($328)) check the STOP key (and some others in A)

View File

@ -79,10 +79,10 @@ asmsub GIVUAYFAY (uword value @ AY) clobbers(A,X,Y) {
; ---- unsigned 16 bit word in A/Y (lo/hi) to fac1
%asm {{
phx
sta P8ZP_SCRATCH_W2
sta _tmp
sty P8ZP_SCRATCH_B1
tya
ldy P8ZP_SCRATCH_W2
ldy _tmp
jsr GIVAYF ; load it as signed... correct afterwards
lda P8ZP_SCRATCH_B1
bpl +
@ -91,6 +91,7 @@ asmsub GIVUAYFAY (uword value @ AY) clobbers(A,X,Y) {
jsr FADD
+ plx
rts
_tmp .byte 0
_flt65536 .byte 145,0,0,0,0 ; 65536.0
}}
}
@ -128,6 +129,14 @@ asmsub GETADRAY () clobbers(X) -> uword @ AY {
}}
}
asmsub FREADUY (ubyte value @Y) {
; -- 8 bit unsigned Y -> float in fac1
%asm {{
lda #0
jmp GIVAYF
}}
}
sub print_f (float value) {
; ---- prints the floating point value (without a newline).
%asm {{

View File

@ -404,7 +404,7 @@ _done
; TODO also mostly usable for lores 4c?
void addr_mul_24_for_highres_4c(y, x) ; 24 bits result is in r0 and r1L (highest byte)
; TODO optimize the loop in pure assembly
; TODO optimize this vertical line loop in pure assembly
color &= 3
color <<= gfx2.plot.shift4c[lsb(x) & 3]
ubyte mask = gfx2.plot.mask4c[lsb(x) & 3]
@ -433,48 +433,46 @@ _done
sub line(uword @zp x1, uword @zp y1, uword @zp x2, uword @zp y2, ubyte color) {
; Bresenham algorithm.
; This code special-cases various quadrant loops to allow simple ++ and -- operations.
; TODO there are some slight errors at the first/last pixels in certain slopes...
if y1>y2 {
; make sure dy is always positive to have only 4 instead of 8 special cases
swap(x1, x2)
swap(y1, y2)
}
word @zp dx = x2-x1 as word
word @zp dy = y2-y1 as word
word @zp dx = (x2 as word)-x1
word @zp dy = (y2 as word)-y1
if dx==0 {
vertical_line(x1, y1, abs(dy)+1 as uword, color)
vertical_line(x1, y1, abs(dy) as uword +1, color)
return
}
if dy==0 {
if x1>x2
x1=x2
horizontal_line(x1, y1, abs(dx)+1 as uword, color)
horizontal_line(x1, y1, abs(dx) as uword +1, color)
return
}
; TODO rewrite the rest in optimized assembly (or reuse GRAPH_draw_line if we can get the FB replacement vector layer working)
word @zp d = 0
ubyte positive_ix = true
cx16.r13 = true ; 'positive_ix'
if dx < 0 {
dx = -dx
positive_ix = false
cx16.r13 = false
}
dx *= 2
dy *= 2
word @zp dx2 = dx*2
word @zp dy2 = dy*2
cx16.r14 = x1 ; internal plot X
if dx >= dy {
if positive_ix {
if cx16.r13 {
repeat {
plot(cx16.r14, y1, color)
if cx16.r14==x2
return
cx16.r14++
d += dy
d += dy2
if d > dx {
y1++
d -= dx
d -= dx2
}
}
} else {
@ -483,25 +481,25 @@ _done
if cx16.r14==x2
return
cx16.r14--
d += dy
d += dy2
if d > dx {
y1++
d -= dx
d -= dx2
}
}
}
}
else {
if positive_ix {
if cx16.r13 {
repeat {
plot(cx16.r14, y1, color)
if y1 == y2
return
y1++
d += dx
d += dx2
if d > dy {
cx16.r14++
d -= dy
d -= dy2
}
}
} else {
@ -510,10 +508,10 @@ _done
if y1 == y2
return
y1++
d += dx
d += dx2
if d > dy {
cx16.r14--
d -= dy
d -= dy2
}
}
}

View File

@ -35,7 +35,7 @@ romsub $FFAE = UNLSN() clobbers(A) ; command serial
romsub $FFB1 = LISTEN(ubyte device @ A) clobbers(A) ; command serial bus device to LISTEN
romsub $FFB4 = TALK(ubyte device @ A) clobbers(A) ; command serial bus device to TALK
romsub $FFB7 = READST() -> ubyte @ A ; read I/O status word
romsub $FFBA = SETLFS(ubyte logical @ A, ubyte device @ X, ubyte address @ Y) ; set logical file parameters
romsub $FFBA = SETLFS(ubyte logical @ A, ubyte device @ X, ubyte secondary @ Y) ; set logical file parameters
romsub $FFBD = SETNAM(ubyte namelen @ A, str filename @ XY) ; set filename parameters
romsub $FFC0 = OPEN() clobbers(X,Y) -> ubyte @Pc, ubyte @A ; (via 794 ($31A)) open a logical file
romsub $FFC3 = CLOSE(ubyte logical @ A) clobbers(A,X,Y) ; (via 796 ($31C)) close a logical file
@ -44,8 +44,8 @@ romsub $FFC9 = CHKOUT(ubyte logical @ X) clobbers(A,X) ; (via 800 ($320
romsub $FFCC = CLRCHN() clobbers(A,X) ; (via 802 ($322)) restore default devices
romsub $FFCF = CHRIN() clobbers(X, Y) -> ubyte @ A ; (via 804 ($324)) input a character (for keyboard, read a whole line from the screen) A=byte read.
romsub $FFD2 = CHROUT(ubyte char @ A) ; (via 806 ($326)) output a character
romsub $FFD5 = LOAD(ubyte verify @ A, uword address @ XY) -> ubyte @Pc, ubyte @ A, ubyte @ X, ubyte @ Y ; (via 816 ($330)) load from device
romsub $FFD8 = SAVE(ubyte zp_startaddr @ A, uword endaddr @ XY) -> ubyte @ Pc, ubyte @ A ; (via 818 ($332)) save to a device
romsub $FFD5 = LOAD(ubyte verify @ A, uword address @ XY) -> ubyte @Pc, ubyte @ A, uword @ XY ; (via 816 ($330)) load from device
romsub $FFD8 = SAVE(ubyte zp_startaddr @ A, uword endaddr @ XY) -> ubyte @ Pc, ubyte @ A ; (via 818 ($332)) save to a device
romsub $FFDB = SETTIM(ubyte low @ A, ubyte middle @ X, ubyte high @ Y) ; set the software clock
romsub $FFDE = RDTIM() -> ubyte @ A, ubyte @ X, ubyte @ Y ; read the software clock
romsub $FFE1 = STOP() clobbers(X) -> ubyte @ Pz, ubyte @ A ; (via 808 ($328)) check the STOP key (and some others in A)
@ -350,75 +350,115 @@ asmsub vaddr(ubyte bank @A, uword address @R0, ubyte addrsel @R1, byte autoIncrO
}
asmsub vpoke(ubyte bank @A, uword address @R0, ubyte value @Y) clobbers(A) {
; -- write a single byte to VERA's video memory
; note: inefficient when writing multiple sequential bytes!
%asm {{
stz cx16.VERA_CTRL
and #1
sta cx16.VERA_ADDR_H
lda cx16.r0
sta cx16.VERA_ADDR_L
lda cx16.r0+1
sta cx16.VERA_ADDR_M
sty cx16.VERA_DATA0
rts
}}
; -- write a single byte to VERA's video memory
; note: inefficient when writing multiple sequential bytes!
%asm {{
stz cx16.VERA_CTRL
and #1
sta cx16.VERA_ADDR_H
lda cx16.r0
sta cx16.VERA_ADDR_L
lda cx16.r0+1
sta cx16.VERA_ADDR_M
sty cx16.VERA_DATA0
rts
}}
}
asmsub vpoke_or(ubyte bank @A, uword address @R0, ubyte value @Y) clobbers (A) {
; -- or a single byte to the value already in the VERA's video memory at that location
; note: inefficient when writing multiple sequential bytes!
%asm {{
stz cx16.VERA_CTRL
and #1
sta cx16.VERA_ADDR_H
lda cx16.r0
sta cx16.VERA_ADDR_L
lda cx16.r0+1
sta cx16.VERA_ADDR_M
tya
ora cx16.VERA_DATA0
sta cx16.VERA_DATA0
rts
}}
; -- or a single byte to the value already in the VERA's video memory at that location
; note: inefficient when writing multiple sequential bytes!
%asm {{
stz cx16.VERA_CTRL
and #1
sta cx16.VERA_ADDR_H
lda cx16.r0
sta cx16.VERA_ADDR_L
lda cx16.r0+1
sta cx16.VERA_ADDR_M
tya
ora cx16.VERA_DATA0
sta cx16.VERA_DATA0
rts
}}
}
asmsub vpoke_and(ubyte bank @A, uword address @R0, ubyte value @Y) clobbers(A) {
; -- and a single byte to the value already in the VERA's video memory at that location
; note: inefficient when writing multiple sequential bytes!
%asm {{
stz cx16.VERA_CTRL
and #1
sta cx16.VERA_ADDR_H
lda cx16.r0
sta cx16.VERA_ADDR_L
lda cx16.r0+1
sta cx16.VERA_ADDR_M
tya
and cx16.VERA_DATA0
sta cx16.VERA_DATA0
rts
}}
; -- and a single byte to the value already in the VERA's video memory at that location
; note: inefficient when writing multiple sequential bytes!
%asm {{
stz cx16.VERA_CTRL
and #1
sta cx16.VERA_ADDR_H
lda cx16.r0
sta cx16.VERA_ADDR_L
lda cx16.r0+1
sta cx16.VERA_ADDR_M
tya
and cx16.VERA_DATA0
sta cx16.VERA_DATA0
rts
}}
}
asmsub vpoke_xor(ubyte bank @A, uword address @R0, ubyte value @Y) clobbers (A) {
; -- xor a single byte to the value already in the VERA's video memory at that location
; note: inefficient when writing multiple sequential bytes!
%asm {{
stz cx16.VERA_CTRL
and #1
sta cx16.VERA_ADDR_H
lda cx16.r0
sta cx16.VERA_ADDR_L
lda cx16.r0+1
sta cx16.VERA_ADDR_M
tya
eor cx16.VERA_DATA0
sta cx16.VERA_DATA0
rts
}}
; -- xor a single byte to the value already in the VERA's video memory at that location
; note: inefficient when writing multiple sequential bytes!
%asm {{
stz cx16.VERA_CTRL
and #1
sta cx16.VERA_ADDR_H
lda cx16.r0
sta cx16.VERA_ADDR_L
lda cx16.r0+1
sta cx16.VERA_ADDR_M
tya
eor cx16.VERA_DATA0
sta cx16.VERA_DATA0
rts
}}
}
asmsub vload(str name @R0, ubyte device @Y, ubyte bank @A, uword address @R1) -> ubyte @A {
; -- like the basic command VLOAD "filename",device,bank,address
; loads a file into video memory in the given bank:address, returns success in A
; !! NOTE !! the V38 ROMs contain a bug in the LOAD code that makes the load address not work correctly,
; it works fine when loading from local filesystem
%asm {{
; -- load a file into video ram
phx
pha
tya
tax
lda #1
ldy #0
jsr c64.SETLFS
lda cx16.r0
ldy cx16.r0+1
jsr prog8_lib.strlen
tya
ldx cx16.r0
ldy cx16.r0+1
jsr c64.SETNAM
pla
clc
adc #2
ldx cx16.r1
ldy cx16.r1+1
stz P8ZP_SCRATCH_B1
jsr c64.LOAD
bcs +
inc P8ZP_SCRATCH_B1
+ jsr c64.CLRCHN
lda #1
jsr c64.CLOSE
plx
lda P8ZP_SCRATCH_B1
rts
}}
}
sub FB_set_pixels_from_buf(uword buffer, uword count) {
%asm {{
; -- This is replacement code for the normal FB_set_pixels subroutine in ROM

View File

@ -1541,3 +1541,71 @@ _negative lsr a
rts
.pend
square .proc
; -- calculate square root of signed word in AY, result in AY
; routine by Lee Davsion, source: http://6502.org/source/integers/square.htm
; using this routine is about twice as fast as doing a regular multiplication.
;
; Calculates the 16 bit unsigned integer square of the signed 16 bit integer in
; Numberl/Numberh. The result is always in the range 0 to 65025 and is held in
; Squarel/Squareh
;
; The maximum input range is only +/-255 and no checking is done to ensure that
; this is so.
;
; This routine is useful if you are trying to draw circles as for any circle
;
; x^2+y^2=r^2 where x and y are the co-ordinates of any point on the circle and
; r is the circle radius
numberl = P8ZP_SCRATCH_W1 ; number to square low byte
numberh = P8ZP_SCRATCH_W1+1 ; number to square high byte
squarel = P8ZP_SCRATCH_W2 ; square low byte
squareh = P8ZP_SCRATCH_W2+1 ; square high byte
tempsq = P8ZP_SCRATCH_B1 ; temp byte for intermediate result
sta numberl
sty numberh
stx P8ZP_SCRATCH_REG
lda #$00 ; clear a
sta squarel ; clear square low byte
; (no need to clear the high byte, it gets shifted out)
lda numberl ; get number low byte
ldx numberh ; get number high byte
bpl _nonneg ; if +ve don't negate it
; else do a two's complement
eor #$ff ; invert
sec ; +1
adc #$00 ; and add it
_nonneg:
sta tempsq ; save abs(number)
ldx #$08 ; set bit count
_nextr2bit:
asl squarel ; low byte *2
rol squareh ; high byte *2+carry from low
asl a ; shift number byte
bcc _nosqadd ; don't do add if c = 0
tay ; save a
clc ; clear carry for add
lda tempsq ; get number
adc squarel ; add number^2 low byte
sta squarel ; save number^2 low byte
lda #$00 ; clear a
adc squareh ; add number^2 high byte
sta squareh ; save number^2 high byte
tya ; get a back
_nosqadd:
dex ; decrement bit count
bne _nextr2bit ; go do next bit
lda squarel
ldy squareh
ldx P8ZP_SCRATCH_REG
rts
.pend

View File

@ -1072,3 +1072,14 @@ sign_extend_AY_byte .proc
rts
.pend
strlen .proc
; -- returns the number of bytes in the string in AY, in Y.
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
ldy #0
- lda (P8ZP_SCRATCH_W1),y
beq +
iny
bne -
+ rts
.pend

View File

@ -1 +1 @@
6.3
6.4

View File

@ -8,6 +8,7 @@ import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.ast.walk.AstWalker
import prog8.ast.walk.IAstModification
import prog8.ast.walk.IAstVisitor
import prog8.compiler.target.ICompilationTarget
@ -154,16 +155,6 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, val errors: I
// The only place for now where we can do this is for:
// asmsub register pair parameter.
if(typecast.type in WordDatatypes) {
val fcall = typecast.parent as? IFunctionCall
if (fcall != null) {
val sub = fcall.target.targetStatement(program) as? Subroutine
if (sub != null && sub.isAsmSubroutine) {
return listOf(IAstModification.ReplaceNode(typecast, typecast.expression, parent))
}
}
}
if(sourceDt in PassByReferenceDatatypes) {
if(typecast.type==DataType.UWORD) {
if(typecast.expression is IdentifierReference) {
@ -216,4 +207,93 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, val errors: I
}
return noModifications
}
override fun after(functionCallStatement: FunctionCallStatement, parent: Node): Iterable<IAstModification> {
if(functionCallStatement.target.nameInSource==listOf("cmp")) {
// if the datatype of the arguments of cmp() are different, cast the byte one to word.
val arg1 = functionCallStatement.args[0]
val arg2 = functionCallStatement.args[1]
val dt1 = arg1.inferType(program).typeOrElse(DataType.STRUCT)
val dt2 = arg2.inferType(program).typeOrElse(DataType.STRUCT)
if(dt1 in ByteDatatypes) {
if(dt2 in ByteDatatypes)
return noModifications
val cast1 = TypecastExpression(arg1, if(dt1==DataType.UBYTE) DataType.UWORD else DataType.WORD, true, functionCallStatement.position)
return listOf(IAstModification.ReplaceNode(arg1, cast1, functionCallStatement))
} else {
if(dt2 in WordDatatypes)
return noModifications
val cast2 = TypecastExpression(arg2, if(dt2==DataType.UBYTE) DataType.UWORD else DataType.WORD, true, functionCallStatement.position)
return listOf(IAstModification.ReplaceNode(arg2, cast2, functionCallStatement))
}
}
return noModifications
}
override fun after(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable<IAstModification> {
val containingStatement = getContainingStatement(arrayIndexedExpression)
if(getComplexArrayIndexedExpressions(containingStatement).size > 1) {
errors.err("it's not possible to use more than one complex array indexing expression in a single statement; break it up via a temporary variable for instance", containingStatement.position)
return noModifications
}
val index = arrayIndexedExpression.indexer.indexExpr
if(index !is NumericLiteralValue && index !is IdentifierReference) {
// replace complex indexing expression with a temp variable to hold the computed index first
return getAutoIndexerVarFor(arrayIndexedExpression)
}
return noModifications
}
private fun getComplexArrayIndexedExpressions(stmt: Statement): List<ArrayIndexedExpression> {
class Searcher : IAstVisitor {
val complexArrayIndexedExpressions = mutableListOf<ArrayIndexedExpression>()
override fun visit(arrayIndexedExpression: ArrayIndexedExpression) {
val ix = arrayIndexedExpression.indexer.indexExpr
if(ix !is NumericLiteralValue && ix !is IdentifierReference)
complexArrayIndexedExpressions.add(arrayIndexedExpression)
}
override fun visit(branchStatement: BranchStatement) {}
override fun visit(forLoop: ForLoop) {}
override fun visit(ifStatement: IfStatement) {
ifStatement.condition.accept(this)
}
override fun visit(untilLoop: UntilLoop) {
untilLoop.condition.accept(this)
}
}
val searcher = Searcher()
stmt.accept(searcher)
return searcher.complexArrayIndexedExpressions
}
private fun getContainingStatement(expression: Expression): Statement {
var node: Node = expression
while(node !is Statement)
node = node.parent
return node
}
private fun getAutoIndexerVarFor(expr: ArrayIndexedExpression): MutableList<IAstModification> {
val modifications = mutableListOf<IAstModification>()
val statement = expr.containingStatement()
// replace the indexer with just the variable (simply use a cx16 virtual register r9, that we HOPE is not used for other things in the expression...)
// assign the indexing expression to the helper variable, but only if that hasn't been done already
val target = AssignTarget(IdentifierReference(listOf("cx16", "r9"), expr.indexer.position), null, null, expr.indexer.position)
val assign = Assignment(target, expr.indexer.indexExpr, expr.indexer.position)
modifications.add(IAstModification.InsertBefore(statement, assign, statement.definingScope()))
modifications.add(IAstModification.ReplaceNode(expr.indexer.indexExpr, target.identifier!!.copy(), expr.indexer))
return modifications
}
}

View File

@ -157,7 +157,7 @@ private class BuiltinFunctionsFacade(functions: Map<String, FSignature>): IBuilt
}
}
else if(func.known_returntype==null)
throw IllegalArgumentException("builtin function $name can't be used here because it doesn't return a value")
return null // builtin function $name can't be used here because it doesn't return a value
}
return null
}
@ -297,7 +297,7 @@ private fun writeAssembly(programAst: Program,
errors: IErrorReporter,
outputDir: Path,
compilerOptions: CompilationOptions): String {
// asm generation directly from the Ast,
// asm generation directly from the Ast
programAst.processAstBeforeAsmGeneration(errors, compilerOptions.compTarget)
errors.report()

View File

@ -374,7 +374,7 @@ internal class AstChecker(private val program: Program,
if(!idt.isKnown) {
errors.err("return type mismatch", assignment.value.position)
}
if(stmt.returntypes.size <= 1 && stmt.returntypes.single() isNotAssignableTo idt.typeOrElse(DataType.BYTE)) {
if(stmt.returntypes.isEmpty() || (stmt.returntypes.size == 1 && stmt.returntypes.single() isNotAssignableTo idt.typeOrElse(DataType.BYTE))) {
errors.err("return type mismatch", assignment.value.position)
}
}
@ -493,7 +493,7 @@ internal class AstChecker(private val program: Program,
fun err(msg: String, position: Position?=null) = errors.err(msg, position ?: decl.position)
// the initializer value can't refer to the variable itself (recursive definition)
if(decl.value?.referencesIdentifier(decl.name) == true || decl.arraysize?.indexVar?.referencesIdentifier(decl.name) == true)
if(decl.value?.referencesIdentifier(decl.name) == true || decl.arraysize?.indexExpr?.referencesIdentifier(decl.name) == true)
err("recursive var declaration")
// CONST can only occur on simple types (byte, word, float)
@ -953,6 +953,20 @@ internal class AstChecker(private val program: Program,
}
}
// functions that don't return a value, can't be used in an expression or assignment
if(targetStatement is Subroutine) {
if(targetStatement.returntypes.isEmpty()) {
if(functionCall.parent is Expression || functionCall.parent is Assignment)
errors.err("subroutine doesn't return a value", functionCall.position)
}
}
else if(targetStatement is BuiltinFunctionStatementPlaceholder) {
if(builtinFunctionReturnType(targetStatement.name, functionCall.args, program).isUnknown) {
if(functionCall.parent is Expression || functionCall.parent is Assignment)
errors.err("function doesn't return a value", functionCall.position)
}
}
super.visit(functionCall)
}
@ -1111,15 +1125,9 @@ internal class AstChecker(private val program: Program,
errors.err("indexing requires a variable to act upon", arrayIndexedExpression.position)
// check index value 0..255
val dtxNum = arrayIndexedExpression.indexer.indexNum?.inferType(program)?.typeOrElse(DataType.STRUCT)
if(dtxNum!=null && dtxNum != DataType.UBYTE && dtxNum != DataType.BYTE)
val dtxNum = arrayIndexedExpression.indexer.indexExpr.inferType(program)
if(!dtxNum.istype(DataType.UBYTE) && !dtxNum.istype(DataType.BYTE))
errors.err("array indexing is limited to byte size 0..255", arrayIndexedExpression.position)
val dtxVar = arrayIndexedExpression.indexer.indexVar?.inferType(program)?.typeOrElse(DataType.STRUCT)
if(dtxVar!=null && dtxVar != DataType.UBYTE && dtxVar != DataType.BYTE)
errors.err("array indexing is limited to byte size 0..255", arrayIndexedExpression.position)
if(arrayIndexedExpression.indexer.origExpression!=null)
throw FatalAstException("array indexer should have been replaced with a temp var @ ${arrayIndexedExpression.indexer.position}")
super.visit(arrayIndexedExpression)
}

View File

@ -1,6 +1,9 @@
package prog8.compiler.astprocessing
import prog8.ast.*
import prog8.ast.IFunctionCall
import prog8.ast.Module
import prog8.ast.Node
import prog8.ast.Program
import prog8.ast.base.*
import prog8.ast.expressions.*
import prog8.ast.statements.*
@ -89,8 +92,7 @@ internal class StatementReorderer(val program: Program, val errors: IErrorReport
if(arrayVar!=null && arrayVar.datatype == DataType.UWORD) {
// rewrite pointervar[index] into @(pointervar+index)
val indexer = arrayIndexedExpression.indexer
val index = (indexer.indexNum ?: indexer.indexVar)!!
val add = BinaryExpression(arrayIndexedExpression.arrayvar, "+", index, arrayIndexedExpression.position)
val add = BinaryExpression(arrayIndexedExpression.arrayvar, "+", indexer.indexExpr, arrayIndexedExpression.position)
return if(parent is AssignTarget) {
// we're part of the target of an assignment, we have to actually change the assign target itself
val memwrite = DirectMemoryWrite(add, arrayIndexedExpression.position)
@ -102,23 +104,7 @@ internal class StatementReorderer(val program: Program, val errors: IErrorReport
}
}
when (val expr2 = arrayIndexedExpression.indexer.origExpression) {
is NumericLiteralValue -> {
arrayIndexedExpression.indexer.indexNum = expr2
arrayIndexedExpression.indexer.origExpression = null
return noModifications
}
is IdentifierReference -> {
arrayIndexedExpression.indexer.indexVar = expr2
arrayIndexedExpression.indexer.origExpression = null
return noModifications
}
is Expression -> {
// replace complex indexing with a temp variable
return getAutoIndexerVarFor(arrayIndexedExpression)
}
else -> return noModifications
}
return noModifications
}
override fun after(expr: BinaryExpression, parent: Node): Iterable<IAstModification> {
@ -202,38 +188,6 @@ internal class StatementReorderer(val program: Program, val errors: IErrorReport
return noModifications
}
private fun getAutoIndexerVarFor(expr: ArrayIndexedExpression): MutableList<IAstModification> {
val modifications = mutableListOf<IAstModification>()
val subroutine = expr.definingSubroutine()!!
val statement = expr.containingStatement()
val indexerVarPrefix = "prog8_autovar_index_"
val repo = subroutine.asmGenInfo.usedAutoArrayIndexerForStatements
// TODO make this a bit smarter so it can reuse indexer variables. BUT BEWARE of scoping+initialization problems then
// add another loop index var to be used for this expression
val indexerVarName = "$indexerVarPrefix${expr.indexer.hashCode()}"
val indexerVar = AsmGenInfo.ArrayIndexerInfo(indexerVarName, expr.indexer)
repo.add(indexerVar)
// create the indexer var at block level scope
val vardecl = VarDecl(VarDeclType.VAR, DataType.UBYTE, ZeropageWish.PREFER_ZEROPAGE,
null, indexerVarName, null, null, isArray = false, autogeneratedDontRemove = true, position = expr.position)
modifications.add(IAstModification.InsertFirst(vardecl, subroutine))
// replace the indexer with just the variable
// assign the indexing expression to the helper variable, but only if that hasn't been done already
val indexerExpression = expr.indexer.origExpression!!
val target = AssignTarget(IdentifierReference(listOf(indexerVar.name), indexerExpression.position), null, null, indexerExpression.position)
val assign = Assignment(target, indexerExpression, indexerExpression.position)
modifications.add(IAstModification.InsertBefore(statement, assign, statement.definingScope()))
modifications.add(IAstModification.SetExpression( {
expr.indexer.indexVar = it as IdentifierReference
expr.indexer.indexNum = null
expr.indexer.origExpression = null
}, target.identifier!!.copy(), expr.indexer))
return modifications
}
override fun after(whenStatement: WhenStatement, parent: Node): Iterable<IAstModification> {
val choices = whenStatement.choiceValues(program).sortedBy {
it.first?.first() ?: Int.MAX_VALUE
@ -344,6 +298,10 @@ internal class StatementReorderer(val program: Program, val errors: IErrorReport
if(targetVar.arraysize==null)
errors.err("array has no defined size", assign.position)
if(assign.value !is IdentifierReference) {
errors.err("invalid array value to assign to other array", assign.value.position)
return noModifications
}
val sourceIdent = assign.value as IdentifierReference
val sourceVar = sourceIdent.targetVarDecl(program)!!
if(!sourceVar.isArray) {
@ -356,7 +314,7 @@ internal class StatementReorderer(val program: Program, val errors: IErrorReport
}
if(!errors.isEmpty())
return emptyList()
return noModifications
val memcopy = FunctionCallStatement(IdentifierReference(listOf("sys", "memcopy"), assign.position),
mutableListOf(

View File

@ -97,6 +97,7 @@ private val functionSignatures: List<FSignature> = listOf(
FSignature("ror2" , false, listOf(FParam("item", setOf(DataType.UBYTE, DataType.UWORD))), null),
FSignature("sort" , false, listOf(FParam("array", ArrayDatatypes)), null),
FSignature("reverse" , false, listOf(FParam("array", ArrayDatatypes)), null),
FSignature("cmp" , false, listOf(FParam("value1", IntegerDatatypes), FParam("value2", NumericDatatypes)), null),
// these few have a return value depending on the argument(s):
FSignature("max" , true, listOf(FParam("values", ArrayDatatypes)), null) { a, p, prg, ct -> collectionArg(a, p, prg, ::builtinMax) }, // type depends on args
FSignature("min" , true, listOf(FParam("values", ArrayDatatypes)), null) { a, p, prg, ct -> collectionArg(a, p, prg, ::builtinMin) }, // type depends on args

View File

@ -109,6 +109,7 @@ internal object C64MachineDefinition: IMachineDefinition {
if (options.zeropage == ZeropageType.FLOATSAFE) {
// remove the zero page locations used for floating point operations from the free list
free.removeAll(listOf(
0x22, 0x23, 0x24, 0x25,
0x10, 0x11, 0x12, 0x26, 0x27, 0x28, 0x29, 0x2a,
0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60,
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,

View File

@ -720,7 +720,10 @@ internal class AsmGen(private val program: Program,
return
}
val indexName = asmVariableName(expr.indexer.indexVar!!)
val indexVar = expr.indexer.indexExpr as? IdentifierReference
?: throw AssemblyError("array indexer should have been replaced with a temp var @ ${expr.indexer.position}")
val indexName = asmVariableName(indexVar)
if(addOneExtra) {
// add 1 to the result
when(elementDt) {

View File

@ -14,11 +14,6 @@ import prog8.compiler.AssemblyError
import prog8.compiler.functions.FSignature
import prog8.compiler.target.CpuType
import prog8.compiler.target.cpu6502.codegen.assignment.*
import prog8.compiler.target.cpu6502.codegen.assignment.AsmAssignSource
import prog8.compiler.target.cpu6502.codegen.assignment.AsmAssignTarget
import prog8.compiler.target.cpu6502.codegen.assignment.AsmAssignment
import prog8.compiler.target.cpu6502.codegen.assignment.SourceStorageKind
import prog8.compiler.target.cpu6502.codegen.assignment.TargetStorageKind
import prog8.compiler.target.subroutineFloatEvalResultVar2
internal class BuiltinFunctionsAsmGen(private val program: Program, private val asmgen: AsmGen, private val assignAsmGen: AssignmentAsmGen) {
@ -69,7 +64,77 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
"peek" -> throw AssemblyError("peek() should have been replaced by @()")
"pokew" -> funcPokeW(fcall)
"poke" -> throw AssemblyError("poke() should have been replaced by @()")
else -> TODO("missing asmgen for builtin func ${func.name}")
"cmp" -> funcCmp(fcall)
else -> throw AssemblyError("missing asmgen for builtin func ${func.name}")
}
}
private fun funcCmp(fcall: IFunctionCall) {
val arg1 = fcall.args[0]
val arg2 = fcall.args[1]
val dt1 = arg1.inferType(program).typeOrElse(DataType.STRUCT)
val dt2 = arg2.inferType(program).typeOrElse(DataType.STRUCT)
if(dt1 in ByteDatatypes) {
if(dt2 in ByteDatatypes) {
when (arg2) {
is IdentifierReference -> {
asmgen.assignExpressionToRegister(arg1, RegisterOrPair.A)
asmgen.out(" cmp ${asmgen.asmVariableName(arg2)}")
}
is NumericLiteralValue -> {
asmgen.assignExpressionToRegister(arg1, RegisterOrPair.A)
asmgen.out(" cmp #${arg2.number}")
}
is DirectMemoryRead -> {
if(arg2.addressExpression is NumericLiteralValue) {
asmgen.assignExpressionToRegister(arg1, RegisterOrPair.A)
asmgen.out(" cmp ${arg2.addressExpression.constValue(program)!!.number.toHex()}")
} else {
asmgen.assignExpressionToVariable(arg2, "P8ZP_SCRATCH_B1", DataType.UBYTE, (fcall as Node).definingSubroutine())
asmgen.assignExpressionToRegister(arg1, RegisterOrPair.A)
asmgen.out(" cmp P8ZP_SCRATCH_B1")
}
}
else -> {
asmgen.assignExpressionToVariable(arg2, "P8ZP_SCRATCH_B1", DataType.UBYTE, (fcall as Node).definingSubroutine())
asmgen.assignExpressionToRegister(arg1, RegisterOrPair.A)
asmgen.out(" cmp P8ZP_SCRATCH_B1")
}
}
} else
throw AssemblyError("args for cmp() should have same dt")
} else {
// dt1 is a word
if(dt2 in WordDatatypes) {
when (arg2) {
is IdentifierReference -> {
asmgen.assignExpressionToRegister(arg1, RegisterOrPair.AY)
asmgen.out("""
cpy ${asmgen.asmVariableName(arg2)}+1
bne +
cmp ${asmgen.asmVariableName(arg2)}
+""")
}
is NumericLiteralValue -> {
asmgen.assignExpressionToRegister(arg1, RegisterOrPair.AY)
asmgen.out("""
cpy #>${arg2.number}
bne +
cmp #<${arg2.number}
+""")
}
else -> {
asmgen.assignExpressionToVariable(arg2, "P8ZP_SCRATCH_W1", DataType.UWORD, (fcall as Node).definingSubroutine())
asmgen.assignExpressionToRegister(arg1, RegisterOrPair.AY)
asmgen.out("""
cpy P8ZP_SCRATCH_W1+1
bne +
cmp P8ZP_SCRATCH_W1
+""")
}
}
} else
throw AssemblyError("args for cmp() should have same dt")
}
}
@ -399,8 +464,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
private fun translateRolRorArrayArgs(arrayvar: IdentifierReference, indexer: ArrayIndex, operation: String, dt: Char) {
asmgen.assignExpressionToVariable(AddressOf(arrayvar, arrayvar.position), "prog8_lib.${operation}_array_u${dt}._arg_target", DataType.UWORD, null)
val indexerExpr = if(indexer.indexVar!=null) indexer.indexVar!! else indexer.indexNum!!
asmgen.assignExpressionToVariable(indexerExpr, "prog8_lib.${operation}_array_u${dt}._arg_index", DataType.UBYTE, null)
asmgen.assignExpressionToVariable(indexer.indexExpr, "prog8_lib.${operation}_array_u${dt}._arg_index", DataType.UBYTE, null)
}
private fun funcVariousFloatFuncs(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, resultRegister: RegisterOrPair?, scope: Subroutine?) {
@ -615,10 +679,10 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
throw AssemblyError("unknown dt")
val elementDt = elementIDt.typeOrElse(DataType.STRUCT)
val firstNum = first.indexer.indexNum
val firstVar = first.indexer.indexVar
val secondNum = second.indexer.indexNum
val secondVar = second.indexer.indexVar
val firstNum = first.indexer.indexExpr as? NumericLiteralValue
val firstVar = first.indexer.indexExpr as? IdentifierReference
val secondNum = second.indexer.indexExpr as? NumericLiteralValue
val secondVar = second.indexer.indexExpr as? IdentifierReference
if(firstNum!=null && secondNum!=null) {
swapArrayValues(elementDt, arrayVarName1, firstNum, arrayVarName2, secondNum)

View File

@ -177,7 +177,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
else
asmgen.out(" lda #0 | sta cx16.${argi.value.second.registerOrPair.toString().toLowerCase()}+1")
}
in WordDatatypes ->
in WordDatatypes, in IterableDatatypes ->
asmgen.out("""
lda P8ESTACK_LO$plusIdxStr,x
sta cx16.${argi.value.second.registerOrPair.toString().toLowerCase()}

View File

@ -66,8 +66,9 @@ internal class PostIncrDecrAsmGen(private val program: Program, private val asmg
targetArrayIdx!=null -> {
val asmArrayvarname = asmgen.asmVariableName(targetArrayIdx.arrayvar)
val elementDt = targetArrayIdx.inferType(program).typeOrElse(DataType.STRUCT)
if(targetArrayIdx.indexer.indexNum!=null) {
val indexValue = targetArrayIdx.indexer.constIndex()!! * program.memsizer.memorySize(elementDt)
val constIndex = targetArrayIdx.indexer.constIndex()
if(constIndex!=null) {
val indexValue = constIndex * program.memsizer.memorySize(elementDt)
when(elementDt) {
in ByteDatatypes -> asmgen.out(if (incr) " inc $asmArrayvarname+$indexValue" else " dec $asmArrayvarname+$indexValue")
in WordDatatypes -> {

View File

@ -120,13 +120,7 @@ internal class AsmAssignSource(val kind: SourceStorageKind,
asmgen.asmVariableName(array.arrayvar)
companion object {
fun fromAstSource(indexer: ArrayIndex, program: Program, asmgen: AsmGen): AsmAssignSource {
return when {
indexer.indexNum!=null -> fromAstSource(indexer.indexNum!!, program, asmgen)
indexer.indexVar!=null -> fromAstSource(indexer.indexVar!!, program, asmgen)
else -> throw AssemblyError("weird indexer")
}
}
fun fromAstSource(indexer: ArrayIndex, program: Program, asmgen: AsmGen): AsmAssignSource = fromAstSource(indexer.indexExpr, program, asmgen)
fun fromAstSource(value: Expression, program: Program, asmgen: AsmGen): AsmAssignSource {
val cv = value.constValue(program)

View File

@ -65,9 +65,10 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
val value = assign.source.array!!
val elementDt = assign.source.datatype
val arrayVarName = asmgen.asmVariableName(value.arrayvar)
if (value.indexer.indexNum!=null) {
val constIndex = value.indexer.constIndex()
if (constIndex!=null) {
// constant array index value
val indexValue = value.indexer.constIndex()!! * program.memsizer.memorySize(elementDt)
val indexValue = constIndex * program.memsizer.memorySize(elementDt)
when (elementDt) {
in ByteDatatypes -> {
asmgen.out(" lda $arrayVarName+$indexValue")
@ -570,11 +571,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
else -> throw AssemblyError("weird type")
}
}
DataType.STR -> {
if (targetDt != DataType.UWORD && targetDt == DataType.STR)
throw AssemblyError("cannot typecast a string into another incompatitble type")
TODO("assign typecasted string into target var")
}
DataType.STR -> throw AssemblyError("cannot typecast a string value")
else -> throw AssemblyError("weird type")
}
}
@ -709,11 +706,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
else -> throw AssemblyError("weird type")
}
}
DataType.STR -> {
if (targetDt != DataType.UWORD && targetDt == DataType.STR)
throw AssemblyError("cannot typecast a string into another incompatitble type")
TODO("assign typecasted string into target var")
}
DataType.STR -> throw AssemblyError("cannot typecast a string value")
else -> throw AssemblyError("weird type")
}
}
@ -1074,11 +1067,11 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
ldy #>${target.asmVarname}
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1""")
if(target.array!!.indexer.indexNum!=null) {
val index = target.array.indexer.constIndex()!!
asmgen.out(" lda #$index")
val constIndex = target.array!!.indexer.constIndex()
if(constIndex!=null) {
asmgen.out(" lda #$constIndex")
} else {
val asmvarname = asmgen.asmVariableName(target.array.indexer.indexVar!!)
val asmvarname = asmgen.asmVariableName(target.array.indexer.indexExpr as IdentifierReference)
asmgen.out(" lda $asmvarname")
}
asmgen.out(" jsr floats.set_array_float_from_fac1")
@ -1110,11 +1103,11 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
ldy #>${target.asmVarname}
sta P8ZP_SCRATCH_W2
sty P8ZP_SCRATCH_W2+1""")
if(target.array!!.indexer.indexNum!=null) {
val index = target.array.indexer.constIndex()!!
asmgen.out(" lda #$index")
val constIndex = target.array!!.indexer.constIndex()
if(constIndex!=null) {
asmgen.out(" lda #$constIndex")
} else {
val asmvarname = asmgen.asmVariableName(target.array.indexer.indexVar!!)
val asmvarname = asmgen.asmVariableName(target.array.indexer.indexExpr as IdentifierReference)
asmgen.out(" lda $asmvarname")
}
asmgen.out(" jsr floats.set_array_float")
@ -1157,11 +1150,11 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
ldy #>${target.asmVarname}
sta P8ZP_SCRATCH_W2
sty P8ZP_SCRATCH_W2+1""")
if(target.array!!.indexer.indexNum!=null) {
val index = target.array.indexer.constIndex()!!
asmgen.out(" lda #$index")
val constIndex = target.array!!.indexer.constIndex()
if(constIndex!=null) {
asmgen.out(" lda #$constIndex")
} else {
val asmvarname = asmgen.asmVariableName(target.array.indexer.indexVar!!)
val asmvarname = asmgen.asmVariableName(target.array.indexer.indexExpr as IdentifierReference)
asmgen.out(" lda $asmvarname")
}
asmgen.out(" jsr floats.set_array_float")
@ -1340,8 +1333,16 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
}
internal fun assignRegisterByte(target: AsmAssignTarget, register: CpuRegister) {
if(target.register !in Cx16VirtualRegisters)
require(target.datatype in ByteDatatypes)
// we make an exception in the type check for assigning something to a cx16 virtual register
if(target.register !in Cx16VirtualRegisters) {
if(target.kind==TargetStorageKind.VARIABLE) {
val parts = target.asmVarname.split('.')
if (parts.size != 2 || parts[0] != "cx16")
require(target.datatype in ByteDatatypes)
} else {
require(target.datatype in ByteDatatypes)
}
}
when(target.kind) {
TargetStorageKind.VARIABLE -> {
@ -1369,7 +1370,8 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
CpuRegister.X -> asmgen.out(" txa")
CpuRegister.Y -> asmgen.out(" tya")
}
asmgen.out(" ldy ${asmgen.asmVariableName(target.array!!.indexer.indexVar!!)} | sta ${target.asmVarname},y")
val indexVar = target.array!!.indexer.indexExpr as IdentifierReference
asmgen.out(" ldy ${asmgen.asmVariableName(indexVar)} | sta ${target.asmVarname},y")
}
}
TargetStorageKind.REGISTER -> {
@ -1777,8 +1779,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
""")
}
TargetStorageKind.ARRAY -> {
if (target.array!!.indexer.indexNum!=null) {
val indexValue = target.array.indexer.constIndex()!! * program.memsizer.memorySize(DataType.FLOAT)
val constIndex = target.array!!.indexer.constIndex()
if (constIndex!=null) {
val indexValue = constIndex * program.memsizer.memorySize(DataType.FLOAT)
if(asmgen.isTargetCpu(CpuType.CPU65c02))
asmgen.out("""
stz ${target.asmVarname}+$indexValue
@ -1797,7 +1800,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
sta ${target.asmVarname}+$indexValue+4
""")
} else {
val asmvarname = asmgen.asmVariableName(target.array.indexer.indexVar!!)
val asmvarname = asmgen.asmVariableName(target.array.indexer.indexExpr as IdentifierReference)
asmgen.out("""
lda #<${target.asmVarname}
sta P8ZP_SCRATCH_W1
@ -1842,8 +1845,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
}
TargetStorageKind.ARRAY -> {
val arrayVarName = target.asmVarname
if (target.array!!.indexer.indexNum!=null) {
val indexValue = target.array.indexer.constIndex()!! * program.memsizer.memorySize(DataType.FLOAT)
val constIndex = target.array!!.indexer.constIndex()
if (constIndex!=null) {
val indexValue = constIndex * program.memsizer.memorySize(DataType.FLOAT)
asmgen.out("""
lda $constFloat
sta $arrayVarName+$indexValue
@ -1857,7 +1861,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
sta $arrayVarName+$indexValue+4
""")
} else {
val asmvarname = asmgen.asmVariableName(target.array.indexer.indexVar!!)
val asmvarname = asmgen.asmVariableName(target.array.indexer.indexExpr as IdentifierReference)
asmgen.out("""
lda #<${constFloat}
sta P8ZP_SCRATCH_W1

View File

@ -199,9 +199,11 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
}
TargetStorageKind.ARRAY -> {
with(target.array!!.indexer) {
val indexNum = indexExpr as? NumericLiteralValue
val indexVar = indexExpr as? IdentifierReference
when {
indexNum!=null -> {
val targetVarName = "${target.asmVarname} + ${indexNum!!.number.toInt()*program.memsizer.memorySize(target.datatype)}"
val targetVarName = "${target.asmVarname} + ${indexNum.number.toInt()*program.memsizer.memorySize(target.datatype)}"
when(target.datatype) {
in ByteDatatypes -> {
when {
@ -268,8 +270,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
}
}
}
TargetStorageKind.REGISTER -> TODO("reg in-place modification")
TargetStorageKind.STACK -> TODO("stack in-place modification")
TargetStorageKind.REGISTER -> throw AssemblyError("missing codegen for reg in-place modification")
TargetStorageKind.STACK -> throw AssemblyError("missing codegen for stack in-place modification")
}
}
@ -320,7 +322,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
"&", "and" -> asmgen.out(" and P8ZP_SCRATCH_B1")
"|", "or" -> asmgen.out(" ora P8ZP_SCRATCH_B1")
"^", "xor" -> asmgen.out(" eor P8ZP_SCRATCH_B1")
in comparisonOperators -> TODO("in-place modification for $operator")
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
if(ptrOnZp)
@ -361,7 +362,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
"&", "and" -> asmgen.out(" and $otherName")
"|", "or" -> asmgen.out(" ora $otherName")
"^", "xor" -> asmgen.out(" eor $otherName")
in comparisonOperators -> TODO("in-place modification for $operator")
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
if(ptrOnZp)
@ -464,7 +464,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
}
in comparisonOperators -> TODO("in-place modification for $operator")
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
}
@ -540,7 +539,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
asmgen.out(" eor $name | sta $name")
}
in comparisonOperators -> TODO("in-place modification for $operator")
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
}
@ -598,7 +596,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
"&", "and" -> asmgen.out(" lda $name | and $otherName | sta $name")
"|", "or" -> asmgen.out(" lda $name | ora $otherName | sta $name")
"^", "xor" -> asmgen.out(" lda $name | eor $otherName | sta $name")
in comparisonOperators -> TODO("in-place modification for $operator")
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
}
@ -670,7 +667,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
"&", "and" -> asmgen.out(" lda $name | and #$value | sta $name")
"|", "or" -> asmgen.out(" lda $name | ora #$value | sta $name")
"^", "xor" -> asmgen.out(" lda $name | eor #$value | sta $name")
in comparisonOperators -> TODO("in-place modification for $operator")
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
}
@ -978,7 +974,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
else -> asmgen.out(" lda $name | eor #<$value | sta $name | lda $name+1 | eor #>$value | sta $name+1")
}
}
in comparisonOperators -> TODO("in-place modification for $operator")
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
}
@ -1054,8 +1049,49 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
lda math.multiply_words.result+1
sta $name+1""")
}
"/" -> TODO("div (u)wordvar/bytevar")
"%" -> TODO("(u)word remainder bytevar")
"/" -> {
if(dt==DataType.UWORD) {
asmgen.out("""
lda $name
ldy $name+1
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
lda $otherName
ldy #0
jsr math.divmod_uw_asm
sta $name
sty $name+1
""")
} else {
asmgen.out("""
lda $name
ldy $name+1
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
lda $otherName
ldy #0
jsr math.divmod_w_asm
sta $name
sty $name+1
""")
}
}
"%" -> {
if(valueDt!=DataType.UBYTE || dt!=DataType.UWORD)
throw AssemblyError("remainder of signed integers is not properly defined/implemented, use unsigned instead")
asmgen.out("""
lda $name
ldy $name+1
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
lda $otherName
ldy #0
jsr math.divmod_uw_asm
lda P8ZP_SCRATCH_W2
sta $name
lda P8ZP_SCRATCH_W2+1
sta $name+1
""") }
"<<" -> {
asmgen.out("""
ldy $otherName
@ -1100,7 +1136,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
}
"|", "or" -> asmgen.out(" lda $otherName | ora $name | sta $name")
"^", "xor" -> asmgen.out(" lda $otherName | eor $name | sta $name")
in comparisonOperators -> TODO("in-place modification for $operator")
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
}
@ -1174,7 +1209,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
"&", "and" -> asmgen.out(" lda $name | and $otherName | sta $name | lda $name+1 | and $otherName+1 | sta $name+1")
"|", "or" -> asmgen.out(" lda $name | ora $otherName | sta $name | lda $name+1 | ora $otherName+1 | sta $name+1")
"^", "xor" -> asmgen.out(" lda $name | eor $otherName | sta $name | lda $name+1 | eor $otherName+1 | sta $name+1")
in comparisonOperators -> TODO("in-place modification for $operator")
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
}
@ -1365,7 +1399,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
asmgen.out(" eor $name | sta $name")
}
in comparisonOperators -> TODO("in-place modification for $operator")
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
}
@ -1406,7 +1439,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY)
asmgen.out(" eor $name | sta $name | tya | eor $name+1 | sta $name+1")
}
in comparisonOperators -> TODO("in-place modification for $operator")
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
}
@ -1454,7 +1486,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
jsr floats.FDIV
""")
}
in comparisonOperators -> TODO("in-place float modification for $operator")
else -> throw AssemblyError("invalid operator for in-place float modification $operator")
}
asmgen.out("""
@ -1535,7 +1566,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
jsr floats.FDIV
""")
}
in comparisonOperators -> TODO("in-place float modification for $operator")
else -> throw AssemblyError("invalid operator for in-place float modification $operator")
}
// store Fac1 back into memory
@ -1620,7 +1650,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
jsr floats.FDIV
""")
}
in comparisonOperators -> TODO("in-place float modification for $operator")
else -> throw AssemblyError("invalid operator for in-place float modification $operator")
}
// store Fac1 back into memory
@ -1730,9 +1759,9 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
}
}
}
TargetStorageKind.ARRAY -> TODO("in-place not of ubyte array")
TargetStorageKind.REGISTER -> TODO("reg not")
TargetStorageKind.STACK -> TODO("stack not")
TargetStorageKind.ARRAY -> throw AssemblyError("missing codegen for in-place not of ubyte array")
TargetStorageKind.REGISTER -> throw AssemblyError("missing codegen for reg not")
TargetStorageKind.STACK -> throw AssemblyError("missing codegen for stack not")
}
}
DataType.UWORD -> {
@ -1749,9 +1778,9 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
sta ${target.asmVarname}+1""")
}
TargetStorageKind.MEMORY -> throw AssemblyError("no asm gen for uword-memory not")
TargetStorageKind.ARRAY -> TODO("in-place not of uword array")
TargetStorageKind.REGISTER -> TODO("reg not")
TargetStorageKind.STACK -> TODO("stack not")
TargetStorageKind.ARRAY -> throw AssemblyError("missing codegen for in-place not of uword array")
TargetStorageKind.REGISTER -> throw AssemblyError("missing codegen for reg not")
TargetStorageKind.STACK -> throw AssemblyError("missing codegen for stack not")
}
}
else -> throw AssemblyError("boolean-not of invalid type")
@ -1796,9 +1825,9 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
}
}
}
TargetStorageKind.ARRAY -> TODO("in-place invert ubyte array")
TargetStorageKind.REGISTER -> TODO("reg invert")
TargetStorageKind.STACK -> TODO("stack invert")
TargetStorageKind.ARRAY -> throw AssemblyError("missing codegen for in-place invert ubyte array")
TargetStorageKind.REGISTER -> throw AssemblyError("missing codegen for reg invert")
TargetStorageKind.STACK -> throw AssemblyError("missing codegen for stack invert")
}
}
DataType.UWORD -> {
@ -1813,9 +1842,9 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
sta ${target.asmVarname}+1""")
}
TargetStorageKind.MEMORY -> throw AssemblyError("no asm gen for uword-memory invert")
TargetStorageKind.ARRAY -> TODO("in-place invert uword array")
TargetStorageKind.REGISTER -> TODO("reg invert")
TargetStorageKind.STACK -> TODO("stack invert")
TargetStorageKind.ARRAY -> throw AssemblyError("missing codegen for in-place invert uword array")
TargetStorageKind.REGISTER -> throw AssemblyError("missing codegen for reg invert")
TargetStorageKind.STACK -> throw AssemblyError("missing codegen for stack invert")
}
}
else -> throw AssemblyError("invert of invalid type")
@ -1834,9 +1863,9 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
sta ${target.asmVarname}""")
}
TargetStorageKind.MEMORY -> throw AssemblyError("can't in-place negate memory ubyte")
TargetStorageKind.ARRAY -> TODO("in-place negate byte array")
TargetStorageKind.REGISTER -> TODO("reg negate")
TargetStorageKind.STACK -> TODO("stack negate")
TargetStorageKind.ARRAY -> throw AssemblyError("missing codegen for in-place negate byte array")
TargetStorageKind.REGISTER -> throw AssemblyError("missing codegen for reg negate")
TargetStorageKind.STACK -> throw AssemblyError("missing codegen for stack negate")
}
}
DataType.WORD -> {
@ -1851,10 +1880,10 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
sbc ${target.asmVarname}+1
sta ${target.asmVarname}+1""")
}
TargetStorageKind.ARRAY -> TODO("in-place negate word array")
TargetStorageKind.ARRAY -> throw AssemblyError("missing codegen for in-place negate word array")
TargetStorageKind.MEMORY -> throw AssemblyError("no asm gen for word memory negate")
TargetStorageKind.REGISTER -> TODO("reg negate")
TargetStorageKind.STACK -> TODO("stack negate")
TargetStorageKind.REGISTER -> throw AssemblyError("missing codegen for reg negate")
TargetStorageKind.STACK -> throw AssemblyError("missing codegen for stack negate")
}
}
DataType.FLOAT -> {
@ -1867,8 +1896,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
sta ${target.asmVarname}+1
""")
}
TargetStorageKind.ARRAY -> TODO("in-place negate float array")
TargetStorageKind.STACK -> TODO("stack float negate")
TargetStorageKind.ARRAY -> throw AssemblyError("missing codegen for in-place negate float array")
TargetStorageKind.STACK -> throw AssemblyError("missing codegen for stack float negate")
else -> throw AssemblyError("weird target kind for float")
}
}

View File

@ -75,7 +75,7 @@ internal class ConstantIdentifierReplacer(private val program: Program, private
override fun before(decl: VarDecl, parent: Node): Iterable<IAstModification> {
// the initializer value can't refer to the variable itself (recursive definition)
// TODO: use call graph for this?
if(decl.value?.referencesIdentifier(decl.name) == true || decl.arraysize?.indexVar?.referencesIdentifier(decl.name) == true) {
if(decl.value?.referencesIdentifier(decl.name) == true || decl.arraysize?.indexExpr?.referencesIdentifier(decl.name) == true) {
errors.err("recursive var declaration", decl.position)
return noModifications
}
@ -93,19 +93,6 @@ internal class ConstantIdentifierReplacer(private val program: Program, private
decl
))
}
} else if(arraysize.constIndex()==null) {
// see if we can calculate the size from other fields
try {
val cval = arraysize.indexVar?.constValue(program) ?: arraysize.origExpression?.constValue(program)
if (cval != null) {
arraysize.indexVar = null
arraysize.origExpression = null
arraysize.indexNum = cval
}
} catch (x: UndefinedSymbolError) {
errors.err(x.message, x.position)
return noModifications
}
}
}

View File

@ -56,9 +56,10 @@ internal class StatementOptimizer(private val program: Program,
}
if(subroutine !in callgraph.usedSymbols && !forceOutput) {
if(!subroutine.isAsmSubroutine)
if(!subroutine.isAsmSubroutine) {
errors.warn("removing unused subroutine '${subroutine.name}'", subroutine.position)
return listOf(IAstModification.Remove(subroutine, subroutine.definingScope()))
return listOf(IAstModification.Remove(subroutine, subroutine.definingScope()))
}
}
return noModifications

View File

@ -25,6 +25,7 @@ internal class UnusedCodeRemover(private val program: Program,
val removals = mutableListOf<IAstModification>()
// remove all subroutines that aren't called, or are empty
// NOTE: part of this is also done already in the StatementOptimizer
val entrypoint = program.entrypoint()
program.modules.forEach {
callgraph.forAllSubroutines(it) { sub ->

View File

@ -191,7 +191,7 @@ class TestC64Zeropage {
val zp1 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true, false, C64Target))
assertEquals(18, zp1.available())
val zp2 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FLOATSAFE, emptyList(), false, false, C64Target))
assertEquals(89, zp2.available())
assertEquals(85, zp2.available())
val zp3 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.KERNALSAFE, emptyList(), false, false, C64Target))
assertEquals(125, zp3.available())
val zp4 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, C64Target))

View File

@ -0,0 +1,13 @@
.PHONY: all clean test
all: test
clean:
rm -f *.prg *.asm *.vice-*
test: clean
p8compile -target cx16 *.p8 >/dev/null
for program in *.prg; do \
echo "RUNNING:" $$program ; \
x16emu -run -prg $$program >/dev/null ; \
done

View File

@ -0,0 +1,18 @@
.PHONY: all clean test
all: test
clean:
rm -f *.prg *.asm *.vice-* test_*.p8
test: clean generate test_prgs
generate:
python make_tests.py
p8compile -noopt -target cx16 *.p8 >/dev/null
test_prgs:
for program in *.prg; do \
echo "RUNNING:" $$program ; \
x16emu -run -prg $$program >/dev/null ; \
done

View File

@ -0,0 +1,508 @@
# generates various Prog8 files with a huge amount of number comparion tests,
# for all supported datatypes and all comparison operators.
import sys
index = 0
def minmaxvalues(dt):
if dt == "ubyte":
return 0, 255
elif dt == "uword":
return 0, 65535
elif dt == "byte":
return -128, 127
elif dt == "word":
return -32768, 32767
elif dt == "float":
return -99999999, 99999999
else:
raise ValueError(dt)
def gen_test(dt, comparison, left, right, expected):
global index
etxt = f"{left} {comparison} {right}"
if eval(etxt) != expected:
raise ValueError("invalid comparison: "+etxt+" for "+dt)
if expected:
stmt_ok = lambda ix: "num_successes++"
stmt_else = lambda ix: f"error({ix})"
else:
stmt_ok = lambda ix: f"error({ix})"
stmt_else = lambda ix: "num_successes++"
def c(number):
if dt not in ("byte", "ubyte"):
return f"({number} as {dt})"
return str(number)
print(
f""" left = {c(left)}
right = {c(right)}
"""
)
# const <op> const
index += 1
print(
f""" ; test #{index}
if {c(left)} {comparison} {c(right)} {{
{stmt_ok(index)}
}} else {{
{stmt_else(index)}
}}
""")
# const <op> var
index += 1
print(
f""" ; test #{index}
if {c(left)} {comparison} right {{
{stmt_ok(index)}
}} else {{
{stmt_else(index)}
}}
""")
# const <op> expr
index += 1
print(
f""" ; test #{index}
if {c(left)} {comparison} right+zero {{
{stmt_ok(index)}
}} else {{
{stmt_else(index)}
}}
""")
# var <op> const
index += 1
print(
f""" ; test #{index}
if left {comparison} {c(right)} {{
{stmt_ok(index)}
}} else {{
{stmt_else(index)}
}}
""")
# var <op> var
index += 1
print(
f""" ; test #{index}
if left {comparison} right {{
{stmt_ok(index)}
}} else {{
{stmt_else(index)}
}}
""")
# var <op> expr
index += 1
print(
f""" ; test #{index}
if left {comparison} right+zero {{
{stmt_ok(index)}
}} else {{
{stmt_else(index)}
}}
""")
# expr <op> const
index += 1
print(
f""" ; test #{index}
if left+zero {comparison} {c(right)} {{
{stmt_ok(index)}
}} else {{
{stmt_else(index)}
}}
""")
# expr <op> var
index += 1
print(
f""" ; test #{index}
if left+zero {comparison} right {{
{stmt_ok(index)}
}} else {{
{stmt_else(index)}
}}
""")
# expr <op> expr
index += 1
print(
f""" ; test #{index}
if left+zero {comparison} right+zero {{
{stmt_ok(index)}
}} else {{
{stmt_else(index)}
}}
""")
def gen_comp_header(dt, operator):
print(" ; tests: ", dt, operator)
print(" comparison = \""+operator+"\"")
print(" txt.print(datatype)")
print(" txt.spc()")
print(" txt.print(comparison)")
print(" txt.nl()")
def gen_comp_equal(dt):
minval, maxval = minmaxvalues(dt)
gen_comp_header(dt, "==")
gen_test(dt, "==", 0, 0, True)
gen_test(dt, "==", 0, 1, False)
gen_test(dt, "==", 100, 100, True)
gen_test(dt, "==", 100, 101, False)
if maxval >= 200:
gen_test(dt, "==", 200, 200, True)
gen_test(dt, "==", 200, 201, False)
if maxval >= 9999:
gen_test(dt, "==", 9999, 9999, True)
gen_test(dt, "==", 9999, 10000, False)
gen_test(dt, "==", 0x5000, 0x5000, True)
gen_test(dt, "==", 0x5000, 0x5001, False)
gen_test(dt, "==", 0x5000, 0x4fff, False)
if maxval >= 30000:
gen_test(dt, "==", 30000, 30000, True)
gen_test(dt, "==", 30000, 30001, False)
if maxval >= 40000:
gen_test(dt, "==", 0xf000, 0xf000, True)
gen_test(dt, "==", 0xf000, 0xf001, False)
gen_test(dt, "==", 0xf000, 0xffff, False)
if minval < 0:
gen_test(dt, "==", 0, -1, False)
gen_test(dt, "==", -100, -100, True)
if minval < -200:
gen_test(dt, "==", -200, -200, True)
gen_test(dt, "==", -200, -201, False)
if minval < -9999:
gen_test(dt, "==", -0x5000, -0x5000, True)
gen_test(dt, "==", -0x5000, -0x5001, False)
gen_test(dt, "==", -0x5000, -0x4fff, False)
gen_test(dt, "==", -9999, -9999, True)
gen_test(dt, "==", -9999, -10000, False)
gen_test(dt, "==", minval, minval, True)
gen_test(dt, "==", minval, minval+1, False)
gen_test(dt, "==", maxval, maxval, True)
gen_test(dt, "==", maxval, maxval-1, False)
def gen_comp_notequal(dt):
minval, maxval = minmaxvalues(dt)
gen_comp_header(dt, "!=")
gen_test(dt, "!=", 0, 0, False)
gen_test(dt, "!=", 0, 1, True)
gen_test(dt, "!=", 100, 100, False)
gen_test(dt, "!=", 100, 101, True)
if maxval >= 200:
gen_test(dt, "!=", 200, 200, False)
gen_test(dt, "!=", 200, 201, True)
if maxval >= 9999:
gen_test(dt, "!=", 9999, 9999, False)
gen_test(dt, "!=", 9999, 10000, True)
gen_test(dt, "!=", 0x5000, 0x5000, False)
gen_test(dt, "!=", 0x5000, 0x5001, True)
gen_test(dt, "!=", 0x5000, 0x4fff, True)
if maxval >= 30000:
gen_test(dt, "!=", 30000, 30000, False)
gen_test(dt, "!=", 30000, 30001, True)
if maxval >= 40000:
gen_test(dt, "!=", 0xf000, 0xf000, False)
gen_test(dt, "!=", 0xf000, 0xf001, True)
gen_test(dt, "!=", 0xf000, 0xffff, True)
if minval < 0:
gen_test(dt, "!=", 0, -1, True)
gen_test(dt, "!=", -100, -100, False)
if minval < -200:
gen_test(dt, "!=", -200, -200, False)
gen_test(dt, "!=", -200, -201, True)
if minval < -9999:
gen_test(dt, "!=", -0x5000, -0x5000, False)
gen_test(dt, "!=", -0x5000, -0x5001, True)
gen_test(dt, "!=", -0x5000, -0x4fff, True)
gen_test(dt, "!=", -9999, -9999, False)
gen_test(dt, "!=", -9999, -10000, True)
gen_test(dt, "!=", minval, minval, False)
gen_test(dt, "!=", minval, minval+1, True)
gen_test(dt, "!=", maxval, maxval, False)
gen_test(dt, "!=", maxval, maxval-1, True)
def gen_comp_less(dt):
minval, maxval = minmaxvalues(dt)
gen_comp_header(dt, "<")
gen_test(dt, "<", 0, 0, False)
gen_test(dt, "<", 0, 1, True)
gen_test(dt, "<", 100, 100, False)
gen_test(dt, "<", 100, 101, True)
gen_test(dt, "<", 100, 99, False)
if maxval >= 200:
gen_test(dt, "<", 200, 200, False)
gen_test(dt, "<", 200, 201, True)
gen_test(dt, "<", 200, 199, False)
if maxval >= 9999:
gen_test(dt, "<", 9999, 9999, False)
gen_test(dt, "<", 9999, 10000, True)
gen_test(dt, "<", 9999, 9998, False)
gen_test(dt, "<", 0x5000, 0x5000, False)
gen_test(dt, "<", 0x5000, 0x5001, True)
gen_test(dt, "<", 0x5000, 0x4fff, False)
if maxval >= 30000:
gen_test(dt, "<", 30000, 30000, False)
gen_test(dt, "<", 30000, 30001, True)
gen_test(dt, "<", 30000, 29999, False)
if maxval >= 40000:
gen_test(dt, "<", 0xf000, 0xf000, False)
gen_test(dt, "<", 0xf000, 0xf001, True)
gen_test(dt, "<", 0xf000, 0xefff, False)
if minval < 0:
gen_test(dt, "<", 0, -1, False)
gen_test(dt, "<", -100, -100, False)
gen_test(dt, "<", -100, -101, False)
gen_test(dt, "<", -100, -99, True)
if minval < -200:
gen_test(dt, "<", -200, -200, False)
gen_test(dt, "<", -200, -201, False)
gen_test(dt, "<", -200, -199, True)
if minval < -9999:
gen_test(dt, "<", -0x5000, -0x5000, False)
gen_test(dt, "<", -0x5000, -0x5001, False)
gen_test(dt, "<", -0x5000, -0x4fff, True)
gen_test(dt, "<", -9999, -9999, False)
gen_test(dt, "<", -9999, -10000, False)
gen_test(dt, "<", -9999, -9998, True)
def gen_comp_greater(dt):
minval, maxval = minmaxvalues(dt)
gen_comp_header(dt, ">")
gen_test(dt, ">", 0, 0, False)
gen_test(dt, ">", 0, 1, False)
gen_test(dt, ">", 100, 100, False)
gen_test(dt, ">", 100, 101, False)
gen_test(dt, ">", 100, 99, True)
if maxval >= 200:
gen_test(dt, ">", 200, 200, False)
gen_test(dt, ">", 200, 201, False)
gen_test(dt, ">", 200, 199, True)
if maxval >= 9999:
gen_test(dt, ">", 9999, 9999, False)
gen_test(dt, ">", 9999, 10000, False)
gen_test(dt, ">", 9999, 9998, True)
gen_test(dt, ">", 0x5000, 0x5000, False)
gen_test(dt, ">", 0x5000, 0x5001, False)
gen_test(dt, ">", 0x5000, 0x4fff, True)
if maxval >= 30000:
gen_test(dt, ">", 30000, 30000, False)
gen_test(dt, ">", 30000, 30001, False)
gen_test(dt, ">", 30000, 29999, True)
if maxval >= 40000:
gen_test(dt, ">", 0xf000, 0xf000, False)
gen_test(dt, ">", 0xf000, 0xf001, False)
gen_test(dt, ">", 0xf000, 0xefff, True)
if minval < 0:
gen_test(dt, ">", 0, -1, True)
gen_test(dt, ">", -100, -100, False)
gen_test(dt, ">", -100, -101, True)
gen_test(dt, ">", -100, -99, False)
if minval < -200:
gen_test(dt, ">", -200, -200, False)
gen_test(dt, ">", -200, -201, True)
gen_test(dt, ">", -200, -199, False)
if minval < -9999:
gen_test(dt, ">", -0x5000, -0x5000, False)
gen_test(dt, ">", -0x5000, -0x5001, True)
gen_test(dt, ">", -0x5000, -0x4fff, False)
gen_test(dt, ">", -9999, -9999, False)
gen_test(dt, ">", -9999, -10000, True)
gen_test(dt, ">", -9999, -9998, False)
def gen_comp_lessequal(dt):
minval, maxval = minmaxvalues(dt)
gen_comp_header(dt, "<=")
gen_test(dt, "<=", 0, 0, True)
gen_test(dt, "<=", 0, 1, True)
gen_test(dt, "<=", 100, 100, True)
gen_test(dt, "<=", 100, 101, True)
gen_test(dt, "<=", 100, 99, False)
if maxval >= 200:
gen_test(dt, "<=", 200, 200, True)
gen_test(dt, "<=", 200, 201, True)
gen_test(dt, "<=", 200, 199, False)
if maxval >= 9999:
gen_test(dt, "<=", 9999, 9999, True)
gen_test(dt, "<=", 9999, 10000, True)
gen_test(dt, "<=", 9999, 9998, False)
gen_test(dt, "<=", 0x5000, 0x5000, True)
gen_test(dt, "<=", 0x5000, 0x5001, True)
gen_test(dt, "<=", 0x5000, 0x4fff, False)
if maxval >= 30000:
gen_test(dt, "<=", 30000, 30000, True)
gen_test(dt, "<=", 30000, 30001, True)
gen_test(dt, "<=", 30000, 29999, False)
if maxval >= 40000:
gen_test(dt, "<=", 0xf000, 0xf000, True)
gen_test(dt, "<=", 0xf000, 0xf001, True)
gen_test(dt, "<=", 0xf000, 0xefff, False)
if minval < 0:
gen_test(dt, "<=", 0, -1, False)
gen_test(dt, "<=", -100, -100, True)
gen_test(dt, "<=", -100, -101, False)
gen_test(dt, "<=", -100, -99, True)
if minval < -200:
gen_test(dt, "<=", -200, -200, True)
gen_test(dt, "<=", -200, -201, False)
gen_test(dt, "<=", -200, -199, True)
if minval < -9999:
gen_test(dt, "<=", -0x5000, -0x5000, True)
gen_test(dt, "<=", -0x5000, -0x5001, False)
gen_test(dt, "<=", -0x5000, -0x4fff, True)
gen_test(dt, "<=", -9999, -9999, True)
gen_test(dt, "<=", -9999, -10000, False)
gen_test(dt, "<=", -9999, -9998, True)
def gen_comp_greaterequal(dt):
minval, maxval = minmaxvalues(dt)
gen_comp_header(dt, ">=")
gen_test(dt, ">=", 0, 0, True)
gen_test(dt, ">=", 0, 1, False)
gen_test(dt, ">=", 100, 100, True)
gen_test(dt, ">=", 100, 101, False)
gen_test(dt, ">=", 100, 99, True)
if maxval >= 200:
gen_test(dt, ">=", 200, 200, True)
gen_test(dt, ">=", 200, 201, False)
gen_test(dt, ">=", 200, 199, True)
if maxval >= 9999:
gen_test(dt, ">=", 9999, 9999, True)
gen_test(dt, ">=", 9999, 10000, False)
gen_test(dt, ">=", 9999, 9998, True)
gen_test(dt, ">=", 0x5000, 0x5000, True)
gen_test(dt, ">=", 0x5000, 0x5001, False)
gen_test(dt, ">=", 0x5000, 0x4fff, True)
if maxval >= 30000:
gen_test(dt, ">=", 30000, 30000, True)
gen_test(dt, ">=", 30000, 30001, False)
gen_test(dt, ">=", 30000, 29999, True)
if maxval >= 40000:
gen_test(dt, ">=", 0xf000, 0xf000, True)
gen_test(dt, ">=", 0xf000, 0xf001, False)
gen_test(dt, ">=", 0xf000, 0xefff, True)
if minval < 0:
gen_test(dt, ">=", 0, -1, True)
gen_test(dt, ">=", -100, -100, True)
gen_test(dt, ">=", -100, -101, True)
gen_test(dt, ">=", -100, -99, False)
if minval < -200:
gen_test(dt, ">=", -200, -200, True)
gen_test(dt, ">=", -200, -201, True)
gen_test(dt, ">=", -200, -199, False)
if minval < -9999:
gen_test(dt, ">=", -0x5000, -0x5000, True)
gen_test(dt, ">=", -0x5000, -0x5001, True)
gen_test(dt, ">=", -0x5000, -0x4fff, False)
gen_test(dt, ">=", -9999, -9999, True)
gen_test(dt, ">=", -9999, -10000, True)
gen_test(dt, ">=", -9999, -9998, False)
def generate_test_routine_equalsnotequals(dt):
print(f"""
sub test_comparisons() {{
{dt} left
{dt} right
{dt} zero = 0
""")
gen_comp_equal(dt)
gen_comp_notequal(dt)
print(" }")
def generate_test_routine_lessgreater(dt):
print(f"""
sub test_comparisons() {{
{dt} left
{dt} right
{dt} zero = 0
""")
gen_comp_less(dt)
gen_comp_greater(dt)
print(" }")
def generate_test_routine_lessequalsgreaterequals(dt):
print(f"""
sub test_comparisons() {{
{dt} left
{dt} right
{dt} zero = 0
""")
gen_comp_lessequal(dt)
gen_comp_greaterequal(dt)
print(" }")
def generate(dt, operators):
global index
index = 0
print(f"""
%import textio
%import floats
%import test_stack
%zeropage basicsafe
main {{
uword num_errors = 0
uword num_successes = 0
str datatype = "{dt}"
uword comparison
sub start() {{
test_comparisons()
print_results()
test_stack.test()
}}
sub error(uword index) {{
txt.print(" ! error in test ")
txt.print_uw(index)
txt.chrout(' ')
txt.print(datatype)
txt.chrout(' ')
txt.print(comparison)
txt.nl()
num_errors++
}}
""")
if operators=="eq":
generate_test_routine_equalsnotequals(dt)
elif operators=="lt":
generate_test_routine_lessgreater(dt)
elif operators=="lteq":
generate_test_routine_lessequalsgreaterequals(dt)
else:
raise ValueError(operators)
print(f"""
sub print_results() {{
txt.nl()
txt.print("total {index}: ")
txt.print_uw(num_successes)
txt.print(" good, ")
txt.print_uw(num_errors)
txt.print(" errors!\\n")
}}
}}
""")
if __name__ == '__main__':
for dt in ["ubyte", "uword", "byte", "word", "float"]:
sys.stdout = open(f"test_{dt}_eq.p8", "wt")
generate(dt, "eq")
sys.stdout = open(f"test_{dt}_lt.p8", "wt")
generate(dt, "lt")
sys.stdout = open(f"test_{dt}_lteq.p8", "wt")
generate(dt, "lteq")

View File

@ -121,8 +121,7 @@ class AstToSourceCode(val output: (text: String) -> Unit, val program: Program):
output(datatypeString(decl.datatype))
if(decl.arraysize!=null) {
decl.arraysize!!.indexNum?.accept(this)
decl.arraysize!!.indexVar?.accept(this)
decl.arraysize!!.indexExpr.accept(this)
}
if(decl.isArray)
output("]")
@ -365,8 +364,7 @@ class AstToSourceCode(val output: (text: String) -> Unit, val program: Program):
override fun visit(arrayIndexedExpression: ArrayIndexedExpression) {
arrayIndexedExpression.arrayvar.accept(this)
output("[")
arrayIndexedExpression.indexer.indexNum?.accept(this)
arrayIndexedExpression.indexer.indexVar?.accept(this)
arrayIndexedExpression.indexer.indexExpr.accept(this)
output("]")
}

View File

@ -60,7 +60,13 @@ enum class DataType {
enum class CpuRegister {
A,
X,
Y
Y;
fun asRegisterOrPair(): RegisterOrPair = when(this) {
A -> RegisterOrPair.A
X -> RegisterOrPair.X
Y -> RegisterOrPair.Y
}
}
enum class RegisterOrPair {

View File

@ -221,14 +221,20 @@ open class VarDecl(val type: VarDeclType,
value?.linkParents(this)
if(structName!=null) {
val structStmt = definingScope().lookup(listOf(structName), this)
if(structStmt!=null)
struct = definingScope().lookup(listOf(structName), this) as StructDecl
if(structStmt!=null) {
val node = definingScope().lookup(listOf(structName), this)
if(node is StructDecl)
struct = node
else
datatypeErrors.add(SyntaxError("invalid datatype declaration", position))
}
}
}
override fun replaceChildNode(node: Node, replacement: Node) {
// TODO the check that node===value is too strict sometimes, but leaving it out allows for bugs to creep through ... :( Perhaps check when adding the replace if there is already a replace on the same node?
require(replacement is Expression)
require(replacement is Expression && node===value)
// NOTE: ideally you also want to check that node===value but this sometimes crashes the optimizer when queueing multiple node replacements
// just accept the risk of having the wrong node specified in the IAstModification object...
value = replacement
replacement.parent = this
}
@ -274,46 +280,19 @@ class ParameterVarDecl(name: String, declaredDatatype: DataType, position: Posit
: VarDecl(VarDeclType.VAR, declaredDatatype, ZeropageWish.DONTCARE, null, name, null, null, false, true, position)
class ArrayIndex(var origExpression: Expression?, // will be replaced later by either the number or the identifier
class ArrayIndex(var indexExpr: Expression,
override val position: Position) : Node {
// for code simplicity, either indexed via a constant number or via a variable (no arbitrary expressions)
override lateinit var parent: Node
var indexNum: NumericLiteralValue? = origExpression as? NumericLiteralValue
var indexVar: IdentifierReference? = origExpression as? IdentifierReference
init {
if(indexNum!=null || indexVar!=null)
origExpression = null
}
override fun linkParents(parent: Node) {
this.parent = parent
origExpression?.linkParents(this)
indexNum?.linkParents(this)
indexVar?.linkParents(this)
indexExpr.linkParents(this)
}
override fun replaceChildNode(node: Node, replacement: Node) {
require(replacement is Expression)
when {
node===origExpression -> origExpression = replacement
node===indexVar -> {
when (replacement) {
is NumericLiteralValue -> {
indexVar = null
indexNum = replacement
}
is IdentifierReference -> {
indexVar = replacement
indexNum = null
}
else -> {
throw FatalAstException("invalid replace")
}
}
}
else -> throw FatalAstException("invalid replace")
}
if (node===indexExpr) indexExpr = replacement
else throw FatalAstException("invalid replace")
}
companion object {
@ -323,29 +302,16 @@ class ArrayIndex(var origExpression: Expression?, // will be replaced
}
}
fun accept(visitor: IAstVisitor) {
origExpression?.accept(visitor)
indexNum?.accept(visitor)
indexVar?.accept(visitor)
}
fun accept(visitor: AstWalker, parent: Node) {
origExpression?.accept(visitor, this)
indexNum?.accept(visitor, this)
indexVar?.accept(visitor, this)
}
fun accept(visitor: IAstVisitor) = indexExpr.accept(visitor)
fun accept(visitor: AstWalker, parent: Node) = indexExpr.accept(visitor, this)
override fun toString(): String {
return("ArrayIndex($indexNum, $indexVar, pos=$position)")
return("ArrayIndex($indexExpr, pos=$position)")
}
fun constIndex() = indexNum?.number?.toInt()
fun constIndex() = (indexExpr as? NumericLiteralValue)?.number?.toInt()
infix fun isSameAs(other: ArrayIndex): Boolean {
return if(indexNum!=null || indexVar!=null)
indexNum==other.indexNum && indexVar == other.indexVar
else
other.origExpression!=null && origExpression!! isSameAs other.origExpression!!
}
infix fun isSameAs(other: ArrayIndex): Boolean = indexExpr isSameAs other.indexExpr
}
open class Assignment(var target: AssignTarget, var value: Expression, override val position: Position) : Statement() {
@ -645,14 +611,11 @@ class AsmGenInfo {
// Conceptually it should be part of any INameScope.
// But because the resulting code only creates "real" scopes on a subroutine level,
// it's more consistent to only define these attributes on a Subroutine node.
var usedAutoArrayIndexerForStatements = mutableListOf<ArrayIndexerInfo>()
var usedRegsaveA = false
var usedRegsaveX = false
var usedRegsaveY = false
var usedFloatEvalResultVar1 = false
var usedFloatEvalResultVar2 = false
class ArrayIndexerInfo(val name: String, val replaces: ArrayIndex)
}
// the subroutine class covers both the normal user-defined subroutines,

View File

@ -56,7 +56,7 @@ interface IAstModification {
}
}
class ReplaceNode(private val node: Node, private val replacement: Node, private val parent: Node) :
class ReplaceNode(val node: Node, private val replacement: Node, private val parent: Node) :
IAstModification {
override fun perform() {
parent.replaceChildNode(node, replacement)
@ -158,9 +158,19 @@ abstract class AstWalker {
open fun after(whileLoop: WhileLoop, parent: Node): Iterable<IAstModification> = emptyList()
private val modifications = mutableListOf<Triple<IAstModification, Node, Node>>()
// private val modificationsReplacedNodes = mutableSetOf<Pair<Node, Position>>()
private fun track(mods: Iterable<IAstModification>, node: Node, parent: Node) {
for (it in mods) modifications += Triple(it, node, parent)
for (it in mods) {
// if(it is IAstModification.ReplaceNode) {
// val replaceKey = Pair(it.node, it.node.position)
// if(replaceKey in modificationsReplacedNodes)
// throw FatalAstException("there already is a node replacement for $replaceKey - optimizer can't deal with multiple replacements for same node yet. Split the ast modification?")
// else
// modificationsReplacedNodes.add(replaceKey)
// }
modifications += Triple(it, node, parent)
}
}
fun applyModifications(): Int {
@ -169,6 +179,7 @@ abstract class AstWalker {
}
val amount = modifications.size
modifications.clear()
// modificationsReplacedNodes.clear()
return amount
}

View File

@ -739,9 +739,11 @@ sin16(x)
sqrt16(w)
16 bit unsigned integer Square root. Result is unsigned byte.
To do the reverse, squaring an integer, just write ``x*x``.
sqrt(x)
Floating point Square root.
To do the reverse, squaring a floating point number, just write ``x*x`` or ``x**2``.
tan(x)
Tangent.
@ -789,6 +791,12 @@ sort(array)
Miscellaneous
^^^^^^^^^^^^^
cmp(x,y)
Compare the integer value x to integer value y. Doesn't return a value or boolean result, only sets the processor's status bits!
You can use a conditional jumps (``if_cc`` etcetera) to act on this.
Normally you should just use a comparison expression (``x < y``)
lsb(x)
Get the least significant byte of the word x. Equivalent to the cast "x as ubyte".

View File

@ -3,7 +3,6 @@ TODO
====
- optimize several inner loops in gfx2
- fix the bresenham line routines in graphics and gfx2 (sometimes they're a pixel 'off') (or maybe finally just replace them with a proper all-assembly implementation)
- hoist all variable declarations up to the subroutine scope *before* even the constant folding takes place (to avoid undefined symbol errors when referring to a variable from another nested scope in the subroutine)
- optimize swap of two memread values with index, using the same pointer expression/variable, like swap(@(ptr+1), @(ptr+2))
- add a flood fill routine to gfx2?
@ -12,7 +11,7 @@ TODO
- refactor the asmgen into their own submodule?
- refactor the compiler optimizers into their own submodule?
- optimizer: detect variables that are written but never read - mark those as unused too and remove them, such as uword unused = memory("unused222", 20) - also remove the memory slab allocation
- add a compiler option to not remove unused subroutines. this allows for building library programs
- add a compiler option to not remove unused subroutines. this allows for building library programs. But this won't work with 64tass's .proc ...
- make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as ``v_``
- option to load the built-in library files from a directory instead of the embedded ones (for easier library development/debugging)
- c64: make the graphics.BITMAP_ADDRESS configurable (VIC banking)

View File

@ -1,110 +0,0 @@
%import textio
%zeropage basicsafe
; Note: this program is compatible with C64 and CX16.
main {
sub start() {
byte v1
byte v2
v1 = 100
v2 = 127
if v1==v2
txt.print("error in 100==127!\n")
else
txt.print("ok: 100 not == 127\n")
if v1!=v2
txt.print("ok: 100 != 127\n")
else
txt.print("error in 100!=127!\n")
if v1<v2
txt.print("ok: 100 < 127\n")
else
txt.print("error in 100<127!\n")
if v1<=v2
txt.print("ok: 100 <= 127\n")
else
txt.print("error in 100<=127!\n")
if v1>v2
txt.print("error in 100>127!\n")
else
txt.print("ok: 100 is not >127\n")
if v1>=v2
txt.print("error in 100>=127!\n")
else
txt.print("ok: 100 is not >=127\n")
v1 = 125
v2 = 22
if v1==v2
txt.print("error in 125==22!\n")
else
txt.print("ok: 125 not == 22\n")
if v1!=v2
txt.print("ok: 125 != 22\n")
else
txt.print("error in 125!=22!\n")
if v1<v2
txt.print("error in 125<22!\n")
else
txt.print("ok: 125 is not < 22\n")
if v1<=v2
txt.print("error in 125<=22!\n")
else
txt.print("ok: 125 is not <= 22\n")
if v1>v2
txt.print("ok: 125 > 22\n")
else
txt.print("error in 125>22!\n")
if v1>=v2
txt.print("ok: 125 >= 22\n")
else
txt.print("error in 125>=22!\n")
v1 = 22
v2 = 22
if v1==v2
txt.print("ok: 22 == 22\n")
else
txt.print("error in 22==22!\n")
if v1!=v2
txt.print("error in 22!=22!\n")
else
txt.print("ok: 22 is not != 22\n")
if v1<v2
txt.print("error in 22<22!\n")
else
txt.print("ok: 22 is not < 22\n")
if v1<=v2
txt.print("ok: 22 <= 22\n")
else
txt.print("error in 22<=22!\n")
if v1>v2
txt.print("error in 22>22!\n")
else
txt.print("ok: 22 is not > 22\n")
if v1>=v2
txt.print("ok: 22 >= 22\n")
else
txt.print("error in 22>=22!\n")
}
}

View File

@ -1,111 +0,0 @@
%import textio
%import floats
%zeropage basicsafe
; Note: this program is compatible with C64 and CX16.
main {
sub start() {
float v1
float v2
v1 = 1.11
v2 = 699.99
if v1==v2
txt.print("error in 1.11==699.99!\n")
else
txt.print("ok: 1.11 not == 699.99\n")
if v1!=v2
txt.print("ok: 1.11 != 699.99\n")
else
txt.print("error in 1.11!=699.99!\n")
if v1<v2
txt.print("ok: 1.11 < 699.99\n")
else
txt.print("error in 1.11<699.99!\n")
if v1<=v2
txt.print("ok: 1.11 <= 699.99\n")
else
txt.print("error in 1.11<=699.99!\n")
if v1>v2
txt.print("error in 1.11>699.99!\n")
else
txt.print("ok: 1.11 is not >699.99\n")
if v1>=v2
txt.print("error in 1.11>=699.99!\n")
else
txt.print("ok: 1.11 is not >=699.99\n")
v1 = 555.5
v2 = -22.2
if v1==v2
txt.print("error in 555.5==-22.2!\n")
else
txt.print("ok: 555.5 not == -22.2\n")
if v1!=v2
txt.print("ok: 555.5 != -22.2\n")
else
txt.print("error in 555.5!=-22.2!\n")
if v1<v2
txt.print("error in 555.5<-22.2!\n")
else
txt.print("ok: 555.5 is not < -22.2\n")
if v1<=v2
txt.print("error in 555.5<=-22.2!\n")
else
txt.print("ok: 555.5 is not <= -22.2\n")
if v1>v2
txt.print("ok: 555.5 > -22.2\n")
else
txt.print("error in 555.5>-22.2!\n")
if v1>=v2
txt.print("ok: 555.5 >= -22.2\n")
else
txt.print("error in 555.5>=-22.2!\n")
v1 = -22.2
v2 = -22.2
if v1==v2
txt.print("ok: -22.2 == -22.2\n")
else
txt.print("error in -22.2==-22.2!\n")
if v1!=v2
txt.print("error in -22.2!=-22.2!\n")
else
txt.print("ok: -22.2 is not != -22.2\n")
if v1<v2
txt.print("error in -22.2<-22.2!\n")
else
txt.print("ok: -22.2 is not < -22.2\n")
if v1<=v2
txt.print("ok: -22.2 <= -22.2\n")
else
txt.print("error in -22.2<=-22.2!\n")
if v1>v2
txt.print("error in -22.2>-22.2!\n")
else
txt.print("ok: -22.2 is not > -22.2\n")
if v1>=v2
txt.print("ok: -22.2 >= -22.2\n")
else
txt.print("error in -22.2>=-22.2!\n")
}
}

View File

@ -1,111 +0,0 @@
%import textio
%zeropage basicsafe
; Note: this program is compatible with C64 and CX16.
main {
sub start() {
ubyte v1
ubyte v2
v1 = 100
v2 = 200
if v1==v2
txt.print("error in 100==200!\n")
else
txt.print("ok: 100 not == 200\n")
if v1!=v2
txt.print("ok: 100 != 200\n")
else
txt.print("error in 100!=200!\n")
if v1<v2
txt.print("ok: 100 < 200\n")
else
txt.print("error in 100<200!\n")
if v1<=v2
txt.print("ok: 100 <= 200\n")
else
txt.print("error in 100<=200!\n")
if v1>v2
txt.print("error in 100>200!\n")
else
txt.print("ok: 100 is not >200\n")
if v1>=v2
txt.print("error in 100>=200!\n")
else
txt.print("ok: 100 is not >=200\n")
v1 = 155
v2 = 22
if v1==v2
txt.print("error in 155==22!\n")
else
txt.print("ok: 155 not == 22\n")
if v1!=v2
txt.print("ok: 155 != 22\n")
else
txt.print("error in 155!=22!\n")
if v1<v2
txt.print("error in 155<22!\n")
else
txt.print("ok: 155 is not < 22\n")
if v1<=v2
txt.print("error in 155<=22!\n")
else
txt.print("ok: 155 is not <= 22\n")
if v1>v2
txt.print("ok: 155 > 22\n")
else
txt.print("error in 155>22!\n")
if v1>=v2
txt.print("ok: 155 >= 22\n")
else
txt.print("error in 155>=22!\n")
v1 = 22
v2 = 22
if v1==v2
txt.print("ok: 22 == 22\n")
else
txt.print("error in 22==22!\n")
if v1!=v2
txt.print("error in 22!=22!\n")
else
txt.print("ok: 22 is not != 22\n")
if v1<v2
txt.print("error in 22<22!\n")
else
txt.print("ok: 22 is not < 22\n")
if v1<=v2
txt.print("ok: 22 <= 22\n")
else
txt.print("error in 22<=22!\n")
if v1>v2
txt.print("error in 22>22!\n")
else
txt.print("ok: 22 is not > 22\n")
if v1>=v2
txt.print("ok: 22 >= 22\n")
else
txt.print("error in 22>=22!\n")
}
}

View File

@ -1,110 +0,0 @@
%import textio
%zeropage basicsafe
; Note: this program is compatible with C64 and CX16.
main {
sub start() {
uword v1
uword v2
v1 = 100
v2 = 64444
if v1==v2
txt.print("error in 100==64444!\n")
else
txt.print("ok: 100 not == 64444\n")
if v1!=v2
txt.print("ok: 100 != 64444\n")
else
txt.print("error in 100!=64444!\n")
if v1<v2
txt.print("ok: 100 < 64444\n")
else
txt.print("error in 100<64444!\n")
if v1<=v2
txt.print("ok: 100 <= 64444\n")
else
txt.print("error in 100<=64444!\n")
if v1>v2
txt.print("error in 100>64444!\n")
else
txt.print("ok: 100 is not >64444\n")
if v1>=v2
txt.print("error in 100>=64444!\n")
else
txt.print("ok: 100 is not >=64444\n")
v1 = 5555
v2 = 322
if v1==v2
txt.print("error in 5555==322!\n")
else
txt.print("ok: 5555 not == 322\n")
if v1!=v2
txt.print("ok: 5555 != 322\n")
else
txt.print("error in 5555!=322!\n")
if v1<v2
txt.print("error in 5555<322!\n")
else
txt.print("ok: 5555 is not < 322\n")
if v1<=v2
txt.print("error in 5555<=322!\n")
else
txt.print("ok: 5555 is not <= 322\n")
if v1>v2
txt.print("ok: 5555 > 322\n")
else
txt.print("error in 5555>322!\n")
if v1>=v2
txt.print("ok: 5555 >= 322\n")
else
txt.print("error in 5555>=322!\n")
v1 = 322
v2 = 322
if v1==v2
txt.print("ok: 322 == 322\n")
else
txt.print("error in 322==322!\n")
if v1!=v2
txt.print("error in 322!=322!\n")
else
txt.print("ok: 322 is not != 322\n")
if v1<v2
txt.print("error in 322<322!\n")
else
txt.print("ok: 322 is not < 322\n")
if v1<=v2
txt.print("ok: 322 <= 322\n")
else
txt.print("error in 322<=322!\n")
if v1>v2
txt.print("error in 322>322!\n")
else
txt.print("ok: 322 is not > 322\n")
if v1>=v2
txt.print("ok: 322 >= 322\n")
else
txt.print("error in 322>=322!\n")
}
}

View File

@ -1,142 +0,0 @@
%import textio
%zeropage basicsafe
; Note: this program is compatible with C64 and CX16.
main {
sub start() {
word v1
word v2
v1 = 100
v2 = 30333
if v1==v2
txt.print("error in 100==30333!\n")
else
txt.print("ok: 100 not == 30333\n")
if v1!=v2
txt.print("ok: 100 != 30333\n")
else
txt.print("error in 100!=30333!\n")
if v1<v2
txt.print("ok: 100 < 30333\n")
else
txt.print("error in 100<30333!\n")
if v1<=v2
txt.print("ok: 100 <= 30333\n")
else
txt.print("error in 100<=30333!\n")
if v1>v2
txt.print("error in 100>30333!\n")
else
txt.print("ok: 100 is not >30333\n")
if v1>=v2
txt.print("error in 100>=30333!\n")
else
txt.print("ok: 100 is not >=30333\n")
v1 = 125
v2 = -222
if v1==v2
txt.print("error in 125==-222!\n")
else
txt.print("ok: 125 not == -222\n")
if v1!=v2
txt.print("ok: 125 != -222\n")
else
txt.print("error in 125!=-222!\n")
if v1<v2
txt.print("error in 125<-222!\n")
else
txt.print("ok: 125 is not < -222\n")
if v1<=v2
txt.print("error in 125<=-222!\n")
else
txt.print("ok: 125 is not <= -222\n")
if v1>v2
txt.print("ok: 125 > -222\n")
else
txt.print("error in 125>-222!\n")
if v1>=v2
txt.print("ok: 125 >= -222\n")
else
txt.print("error in 125>=-222!\n")
v1 = -222
v2 = -222
if v1==v2
txt.print("ok: -222 == -222\n")
else
txt.print("error in -222==-222!\n")
if v1!=v2
txt.print("error in -222!=-222!\n")
else
txt.print("ok: -222 is not != -222\n")
if v1<v2
txt.print("error in -222<-222!\n")
else
txt.print("ok: -222 is not < -222\n")
if v1<=v2
txt.print("ok: -222 <= -222\n")
else
txt.print("error in -222<=-222!\n")
if v1>v2
txt.print("error in -222>-222!\n")
else
txt.print("ok: -222 is not > -222\n")
if v1>=v2
txt.print("ok: -222 >= -222\n")
else
txt.print("error in -222>=-222!\n")
v1 = 1000
v2 = 1000
if v1==v2
txt.print("ok: 1000 == 1000\n")
else
txt.print("error in 1000==1000!\n")
if v1!=v2
txt.print("error in 1000!=1000!\n")
else
txt.print("ok: 1000 is not != 1000\n")
if v1<v2
txt.print("error in 1000<1000!\n")
else
txt.print("ok: 1000 is not < 1000\n")
if v1<=v2
txt.print("ok: 1000 <= 1000\n")
else
txt.print("error in 1000<=1000!\n")
if v1>v2
txt.print("error in 1000>1000!\n")
else
txt.print("ok: 1000 is not > 1000\n")
if v1>=v2
txt.print("ok: 1000 >= 1000\n")
else
txt.print("error in 1000>=1000!\n")
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,913 +0,0 @@
%import textio
%import floats
%zeropage basicsafe
%import test_stack
main {
sub start() {
word_less()
word_lessequal()
word_greaterequal()
word_greater()
uword_lessequal()
}
sub uword_lessequal() {
uword lessvar
uword comparevar
txt.print("uword <=\n")
txt.print_uw(65535)
txt.nl()
check_lesseq_uw(0, 65535)
txt.print_uw(0)
txt.nl()
check_not_lesseq_uw(65535, 0)
comparevar = 65535
txt.print_uw(comparevar)
txt.nl()
for lessvar in comparevar downto 0 {
check_lesseq_uw(lessvar, comparevar)
}
comparevar = 65535-2
txt.print_uw(comparevar)
txt.nl()
for lessvar in comparevar downto 0 {
check_lesseq_uw(lessvar, comparevar)
}
comparevar = 65535-254
txt.print_uw(comparevar)
txt.nl()
for lessvar in comparevar downto 0 {
check_lesseq_uw(lessvar, comparevar)
}
comparevar = 65535-255
txt.print_uw(comparevar)
txt.nl()
for lessvar in comparevar downto 0 {
check_lesseq_uw(lessvar, comparevar)
}
comparevar = 65535-256
txt.print_uw(comparevar)
txt.nl()
for lessvar in comparevar downto 0 {
check_lesseq_uw(lessvar, comparevar)
}
comparevar = 65535-5000
txt.print_uw(comparevar)
txt.nl()
for lessvar in comparevar downto 0 {
check_lesseq_uw(lessvar, comparevar)
}
comparevar = 32769
txt.print_uw(comparevar)
txt.nl()
for lessvar in comparevar downto 0 {
check_lesseq_uw(lessvar, comparevar)
}
comparevar = 32768
txt.print_uw(comparevar)
txt.nl()
for lessvar in 65535 downto comparevar+1 {
check_not_lesseq_uw(lessvar, comparevar)
}
comparevar = 1
txt.print_uw(comparevar)
txt.nl()
for lessvar in 65535 downto comparevar+1 {
check_not_lesseq_uw(lessvar, comparevar)
}
comparevar = 0
txt.print_uw(comparevar)
txt.nl()
for lessvar in 65535 downto comparevar+1 {
check_not_lesseq_uw(lessvar, comparevar)
}
comparevar = 11111
txt.print_uw(comparevar)
txt.nl()
for lessvar in 65535 downto comparevar+1 {
check_not_lesseq_uw(lessvar, comparevar)
}
comparevar = 255
txt.print_uw(comparevar)
txt.nl()
for lessvar in 65535 downto comparevar+1 {
check_not_lesseq_uw(lessvar, comparevar)
}
comparevar = 256
txt.print_uw(comparevar)
txt.nl()
for lessvar in 65535 downto comparevar+1 {
check_not_lesseq_uw(lessvar, comparevar)
}
test_stack.test()
return
sub check_lesseq_uw(uword w1, uword w2) {
uword zero = 0
ubyte error=0
ubyte ub = w1<=w2
if not ub {
error++
txt.print("ub!")
}
if w1<=(w2+zero) {
zero = 0 ; dummy
} else {
error++
txt.print("c!")
}
if error {
txt.print(" ")
txt.print_uw(w1)
txt.print(" <= ")
txt.print_uw(w2)
txt.nl()
sys.exit(1)
}
}
sub check_not_lesseq_uw(uword w1, uword w2) {
uword zero = 0
ubyte error=0
ubyte ub = w1<=w2
if ub {
error++
txt.print("ub!")
}
if w1<=(w2+zero) {
error++
txt.print("c!")
} else {
zero = 0 ; dummy
}
if error {
txt.print(" ")
txt.print_uw(w1)
txt.print(" not <= ")
txt.print_uw(w2)
txt.nl()
sys.exit(1)
}
}
}
sub word_greater() {
word biggervar
word comparevar
txt.print("word >\n")
txt.print_w(-32767)
txt.nl()
check_greater_w(32767, -32767)
txt.print_w(32766)
txt.nl()
check_not_greater_w(-32766, 32766)
comparevar = 32765
txt.print_w(comparevar)
txt.nl()
for biggervar in comparevar downto -32768 {
check_not_greater_w(biggervar, comparevar)
}
comparevar = -1
txt.print_w(comparevar)
txt.nl()
for biggervar in comparevar downto -32768 {
check_not_greater_w(biggervar, comparevar)
}
comparevar = 0
txt.print_w(comparevar)
txt.nl()
for biggervar in comparevar downto -32768 {
check_not_greater_w(biggervar, comparevar)
}
comparevar = 11111
txt.print_w(comparevar)
txt.nl()
for biggervar in comparevar downto -32768 {
check_not_greater_w(biggervar, comparevar)
}
comparevar = 0
txt.print_w(comparevar)
txt.nl()
for biggervar in 32767 downto comparevar+1 {
check_greater_w(biggervar, comparevar)
}
comparevar = -2
txt.print_w(comparevar)
txt.nl()
for biggervar in 32767 downto comparevar+1 {
check_greater_w(biggervar, comparevar)
}
comparevar = -254
txt.print_w(comparevar)
txt.nl()
for biggervar in 32767 downto comparevar+1 {
check_greater_w(biggervar, comparevar)
}
comparevar = -255
txt.print_w(comparevar)
txt.nl()
for biggervar in 32767 downto comparevar+1 {
check_greater_w(biggervar, comparevar)
}
comparevar = -256
txt.print_w(comparevar)
txt.nl()
for biggervar in 32767 downto comparevar+1 {
check_greater_w(biggervar, comparevar)
}
comparevar = -5000
txt.print_w(comparevar)
txt.nl()
for biggervar in 32767 downto comparevar+1 {
check_greater_w(biggervar, comparevar)
}
comparevar = 1
txt.print_w(comparevar)
txt.nl()
for biggervar in 32767 downto comparevar+1 {
check_greater_w(biggervar, comparevar)
}
comparevar = 255
txt.print_w(comparevar)
txt.nl()
for biggervar in 32767 downto comparevar+1 {
check_greater_w(biggervar, comparevar)
}
comparevar = 256
txt.print_w(comparevar)
txt.nl()
for biggervar in 32767 downto comparevar+1 {
check_greater_w(biggervar, comparevar)
}
comparevar = 257
txt.print_w(comparevar)
txt.nl()
for biggervar in 32767 downto comparevar+1 {
check_greater_w(biggervar, comparevar)
}
comparevar = 32760
txt.print_w(comparevar)
txt.nl()
for biggervar in 32767 downto comparevar+1 {
check_greater_w(biggervar, comparevar)
}
test_stack.test()
return
sub check_greater_w(word w1, word w2) {
word zero = 0
ubyte error=0
ubyte ub = w1>(w2+zero)
if not ub {
error++
txt.print("ubz!")
}
ub = w1>w2
if not ub {
error++
txt.print("ub!")
}
if w1>(w2+zero) {
zero = 0 ; dummy
} else {
error++
txt.print("c!")
}
if error {
txt.print(" ")
txt.print_w(w1)
txt.print(" > ")
txt.print_w(w2)
txt.nl()
sys.exit(1)
}
}
sub check_not_greater_w(word w1, word w2) {
word zero = 0
ubyte error=0
ubyte ub = w1>w2
if ub {
error++
txt.print("ub!")
}
if w1>(w2+zero) {
error++
txt.print("c!")
} else {
zero = 0 ; dummy
}
if w1>w2 {
error++
txt.print("c2!")
} else {
zero = 0 ; dummy
}
if error {
txt.print(" ")
txt.print_w(w1)
txt.print(" not > ")
txt.print_w(w2)
txt.nl()
sys.exit(1)
}
}
}
sub word_greaterequal() {
word biggervar
word comparevar
txt.print("word >=\n")
txt.print_w(-32767)
txt.nl()
check_greatereq_w(32767, -32767)
txt.print_w(32766)
txt.nl()
check_not_greatereq_w(-32766, 32766)
comparevar = 32765
txt.print_w(comparevar)
txt.nl()
for biggervar in comparevar-1 downto -32768 {
check_not_greatereq_w(biggervar, comparevar)
}
comparevar = -1
txt.print_w(comparevar)
txt.nl()
for biggervar in comparevar-1 downto -32768 {
check_not_greatereq_w(biggervar, comparevar)
}
comparevar = 0
txt.print_w(comparevar)
txt.nl()
for biggervar in comparevar-1 downto -32768 {
check_not_greatereq_w(biggervar, comparevar)
}
comparevar = 11111
txt.print_w(comparevar)
txt.nl()
for biggervar in comparevar-1 downto -32768 {
check_not_greatereq_w(biggervar, comparevar)
}
comparevar = 0
txt.print_w(comparevar)
txt.nl()
for biggervar in 32767 downto comparevar {
check_greatereq_w(biggervar, comparevar)
}
comparevar = -2
txt.print_w(comparevar)
txt.nl()
for biggervar in 32767 downto comparevar {
check_greatereq_w(biggervar, comparevar)
}
comparevar = -254
txt.print_w(comparevar)
txt.nl()
for biggervar in 32767 downto comparevar {
check_greatereq_w(biggervar, comparevar)
}
comparevar = -255
txt.print_w(comparevar)
txt.nl()
for biggervar in 32767 downto comparevar {
check_greatereq_w(biggervar, comparevar)
}
comparevar = -256
txt.print_w(comparevar)
txt.nl()
for biggervar in 32767 downto comparevar {
check_greatereq_w(biggervar, comparevar)
}
comparevar = -5000
txt.print_w(comparevar)
txt.nl()
for biggervar in 32767 downto comparevar {
check_greatereq_w(biggervar, comparevar)
}
comparevar = 1
txt.print_w(comparevar)
txt.nl()
for biggervar in 32767 downto comparevar {
check_greatereq_w(biggervar, comparevar)
}
comparevar = 255
txt.print_w(comparevar)
txt.nl()
for biggervar in 32767 downto comparevar {
check_greatereq_w(biggervar, comparevar)
}
comparevar = 256
txt.print_w(comparevar)
txt.nl()
for biggervar in 32767 downto comparevar {
check_greatereq_w(biggervar, comparevar)
}
comparevar = 257
txt.print_w(comparevar)
txt.nl()
for biggervar in 32767 downto comparevar {
check_greatereq_w(biggervar, comparevar)
}
comparevar = 32767
txt.print_w(comparevar)
txt.nl()
for biggervar in 32767 downto comparevar {
check_greatereq_w(biggervar, comparevar)
}
test_stack.test()
return
sub check_greatereq_w(word w1, word w2) {
word zero = 0
ubyte error=0
ubyte ub = w1>=(w2+zero)
if not ub {
error++
txt.print("ubz!")
}
ub = w1>=w2
if not ub {
error++
txt.print("ub!")
}
if w1>=(w2+zero) {
zero = 0 ; dummy
} else {
error++
txt.print("c!")
}
if error {
txt.print(" ")
txt.print_w(w1)
txt.print(" >= ")
txt.print_w(w2)
txt.nl()
sys.exit(1)
}
}
sub check_not_greatereq_w(word w1, word w2) {
word zero = 0
ubyte error=0
ubyte ub = w1>=w2
if ub {
error++
txt.print("ub!")
}
if w1>=(w2+zero) {
error++
txt.print("c!")
} else {
zero = 0 ; dummy
}
if w1>=w2 {
error++
txt.print("c2!")
} else {
zero = 0 ; dummy
}
if error {
txt.print(" ")
txt.print_w(w1)
txt.print(" not >= ")
txt.print_w(w2)
txt.nl()
sys.exit(1)
}
}
}
sub word_lessequal() {
word lessvar
word comparevar
txt.print("word <=\n")
txt.print_w(32767)
txt.nl()
check_lesseq_w(-32767, 32767)
txt.print_w(-32767)
txt.nl()
check_not_lesseq_w(32767, -32767)
comparevar = 0
txt.print_w(comparevar)
txt.nl()
for lessvar in comparevar downto -32768 {
check_lesseq_w(lessvar, comparevar)
}
comparevar = -2
txt.print_w(comparevar)
txt.nl()
for lessvar in comparevar downto -32768 {
check_lesseq_w(lessvar, comparevar)
}
comparevar = -254
txt.print_w(comparevar)
txt.nl()
for lessvar in comparevar downto -32768 {
check_lesseq_w(lessvar, comparevar)
}
comparevar = -255
txt.print_w(comparevar)
txt.nl()
for lessvar in comparevar downto -32768 {
check_lesseq_w(lessvar, comparevar)
}
comparevar = -256
txt.print_w(comparevar)
txt.nl()
for lessvar in comparevar downto -32768 {
check_lesseq_w(lessvar, comparevar)
}
comparevar = -5000
txt.print_w(comparevar)
txt.nl()
for lessvar in comparevar downto -32768 {
check_lesseq_w(lessvar, comparevar)
}
comparevar = 1
txt.print_w(comparevar)
txt.nl()
for lessvar in comparevar downto -32768 {
check_lesseq_w(lessvar, comparevar)
}
comparevar = 255
txt.print_w(comparevar)
txt.nl()
for lessvar in comparevar downto -32768 {
check_lesseq_w(lessvar, comparevar)
}
comparevar = 256
txt.print_w(comparevar)
txt.nl()
for lessvar in comparevar downto -32768 {
check_lesseq_w(lessvar, comparevar)
}
comparevar = 257
txt.print_w(comparevar)
txt.nl()
for lessvar in comparevar downto -32768 {
check_lesseq_w(lessvar, comparevar)
}
comparevar = 32767
txt.print_w(comparevar)
txt.nl()
for lessvar in comparevar downto -32768 {
check_lesseq_w(lessvar, comparevar)
}
comparevar = -32768
txt.print_w(comparevar)
txt.nl()
for lessvar in 32766 downto comparevar+1 {
check_not_lesseq_w(lessvar, comparevar)
}
comparevar = -1
txt.print_w(comparevar)
txt.nl()
for lessvar in 32766 downto comparevar+1 {
check_not_lesseq_w(lessvar, comparevar)
}
comparevar = 0
txt.print_w(comparevar)
txt.nl()
for lessvar in 32766 downto comparevar+1 {
check_not_lesseq_w(lessvar, comparevar)
}
comparevar = 11111
txt.print_w(comparevar)
txt.nl()
for lessvar in 32766 downto comparevar+1 {
check_not_lesseq_w(lessvar, comparevar)
}
test_stack.test()
return
sub check_lesseq_w(word w1, word w2) {
word zero = 0
ubyte error=0
ubyte ub = w1<=w2
if not ub {
error++
txt.print("ub!")
}
if w1<=(w2+zero) {
zero = 0 ; dummy
} else {
error++
txt.print("c!")
}
if error {
txt.print(" ")
txt.print_w(w1)
txt.print(" <= ")
txt.print_w(w2)
txt.nl()
sys.exit(1)
}
}
sub check_not_lesseq_w(word w1, word w2) {
word zero = 0
ubyte error=0
ubyte ub = w1<=w2
if ub {
error++
txt.print("ub!")
}
if w1<=(w2+zero) {
error++
txt.print("c!")
} else {
zero = 0 ; dummy
}
if error {
txt.print(" ")
txt.print_w(w1)
txt.print(" not <= ")
txt.print_w(w2)
txt.nl()
sys.exit(1)
}
}
}
sub word_less() {
word lessvar
word comparevar
txt.print("word <\n")
txt.print_w(32767)
txt.nl()
check_less_w(-32767, 32767)
txt.print_w(-32767)
txt.nl()
check_not_less_w(32767, -32767)
comparevar = 0
txt.print_w(comparevar)
txt.nl()
for lessvar in -1 downto -32768 {
check_less_w(lessvar, comparevar)
}
comparevar = -2
txt.print_w(comparevar)
txt.nl()
for lessvar in -3 downto -32768 {
check_less_w(lessvar, comparevar)
}
comparevar = -254
txt.print_w(comparevar)
txt.nl()
for lessvar in -255 downto -32768 {
check_less_w(lessvar, comparevar)
}
comparevar = -255
txt.print_w(comparevar)
txt.nl()
for lessvar in -256 downto -32768 {
check_less_w(lessvar, comparevar)
}
comparevar = -256
txt.print_w(comparevar)
txt.nl()
for lessvar in -257 downto -32768 {
check_less_w(lessvar, comparevar)
}
comparevar = -5000
txt.print_w(comparevar)
txt.nl()
for lessvar in -5001 downto -32768 {
check_less_w(lessvar, comparevar)
}
comparevar = 1
txt.print_w(comparevar)
txt.nl()
for lessvar in 0 downto -32768 {
check_less_w(lessvar, comparevar)
}
comparevar = 255
txt.print_w(comparevar)
txt.nl()
for lessvar in 254 downto -32768 {
check_less_w(lessvar, comparevar)
}
comparevar = 256
txt.print_w(comparevar)
txt.nl()
for lessvar in 255 downto -32768 {
check_less_w(lessvar, comparevar)
}
comparevar = 257
txt.print_w(comparevar)
txt.nl()
for lessvar in 256 downto -32768 {
check_less_w(lessvar, comparevar)
}
comparevar = 32767
txt.print_w(comparevar)
txt.nl()
for lessvar in 32766 downto -32768 {
check_less_w(lessvar, comparevar)
}
comparevar = -32768
txt.print_w(comparevar)
txt.nl()
for lessvar in 32766 downto -32768 {
check_not_less_w(lessvar, comparevar)
}
comparevar = -1
txt.print_w(comparevar)
txt.nl()
for lessvar in 32766 downto -1 {
check_not_less_w(lessvar, comparevar)
}
comparevar = 0
txt.print_w(comparevar)
txt.nl()
for lessvar in 32766 downto 0 {
check_not_less_w(lessvar, comparevar)
}
comparevar = 11111
txt.print_w(comparevar)
txt.nl()
for lessvar in 32766 downto 11111 {
check_not_less_w(lessvar, comparevar)
}
test_stack.test()
return
sub check_less_w(word w1, word w2) {
word zero = 0
ubyte error=0
ubyte ub = w1<w2
if not ub {
error++
txt.print("ub!")
}
if w1<(w2+zero) {
zero = 0 ; dummy
} else {
error++
txt.print("c!")
}
if error {
txt.print(" ")
txt.print_w(w1)
txt.print(" < ")
txt.print_w(w2)
txt.nl()
sys.exit(1)
}
}
sub check_not_less_w(word w1, word w2) {
word zero = 0
ubyte error=0
ubyte ub = w1<w2
if ub {
error++
txt.print("ub!")
}
if w1<(w2+zero) {
error++
txt.print("c!")
} else {
zero = 0 ; dummy
}
if error {
txt.print(" ")
txt.print_w(w1)
txt.print(" not < ")
txt.print_w(w2)
txt.nl()
sys.exit(1)
}
}
}
}

View File

@ -56,11 +56,11 @@ main {
sub vector_v(uword x, uword y) {
gfx2.horizontal_line(x, y, 12, 1)
gfx2.horizontal_line(x+16, y+16, 12,1)
gfx2.horizontal_line(x+16, y+16, 11,1)
gfx2.line(x,y,x+16,y+16,1)
gfx2.line(x+11,y,x+16+6,y+10,1)
gfx2.line(x+16+6,y+10,x+48,y-16,1)
gfx2.line(x+16+11,y+16,x+48+11,y-16,1)
gfx2.line(x+11,y,x+16+5,y+10,1)
gfx2.line(x+16+5,y+10,x+47,y-16,1)
gfx2.line(x+16+10,y+16,x+46+12,y-16,1)
}
sub window_system() {
@ -200,9 +200,9 @@ widget {
gfx2.horizontal_line(x+width-1-16, y+height-20, 16, 2)
gfx2.horizontal_line(x+width-1-16, y+height-21, 16, 1)
gfx2.horizontal_line(x+width-1-16, y+height-30, 16, 2)
gfx2.line(x+width-1-12, y+height-23, x+width-8, y+height-28, 1)
gfx2.line(x+width-1-13, y+height-23, x+width-9, y+height-28, 1)
gfx2.line(x+width-1-3, y+height-23, x+width-9, y+height-28, 1)
gfx2.line(x+width-1-13, y+height-18, x+width-8, y+height-13, 1)
gfx2.line(x+width-1-13, y+height-18, x+width-9, y+height-13, 1)
gfx2.line(x+width-1-3, y+height-18, x+width-9, y+height-13, 1)
}
}

View File

@ -5,6 +5,7 @@
; Vertical rasterbars a.k.a. "Kefren bars"
; also see: rasterbars.p8
main {
sub start() {

Binary file not shown.

Binary file not shown.

View File

@ -1,12 +1,17 @@
%target cx16
%import textio
%option no_sysinit
%zeropage basicsafe
; simple test program for the "VTUI" text user interface library
; see: https://github.com/JimmyDansbo/VTUIlib
main {
sub start() {
txt.lowercase()
vtui.initialize()
store_logo()
txt.lowercase()
vtui.screen_set(2)
vtui.clr_scr('%', $50)
vtui.gotoxy(5,5)
@ -14,29 +19,46 @@ main {
vtui.gotoxy(10,10)
vtui.border(1, 40, 6, $47)
vtui.gotoxy(12,12)
vtui.print_str(@"Hello, world! vtui from Prog8!", $f2, $80)
vtui.print_str2(@"Hello, world! vtui from Prog8!", $f2, $80)
vtui.gotoxy(12,13)
vtui.print_str("Hello, world! vtui from Prog8!", $f2, $00)
vtui.print_str2("Hello, world! vtui from Prog8!", $f2, $00)
repeat {
}
str inputbuffer = "?" * 20
; txt.print_uwhex(inputbuffer, 1)
; txt.chrout(':')
; txt.print(inputbuffer)
; txt.chrout('\n')
vtui.gotoxy(5,20)
vtui.print_str2(@"Enter your name: ", $e3, $80)
ubyte length = vtui.input_str(inputbuffer, len(inputbuffer), $21)
vtui.gotoxy(8,22)
vtui.print_str2(@"Your name is: ", $e3, $80)
;vtui.print_str2(inputbuffer, $67, $00)
vtui.print_str(inputbuffer, length, $67, $00)
; txt.uppercase() ; kills vtui?
logo_mover()
}
sub store_logo() {
vtui.gotoxy(0, 0)
vtui.save_rect($80, 1, $0000, 7, 7)
vtui.gotoxy(0, 0)
vtui.save_rect($80, 1, $0100, 7, 7)
}
sub logo_mover() {
ubyte xcoord
ubyte ycoord
ubyte newx
ubyte newy
ubyte xcoord = 0
ubyte ycoord = 0
ubyte newx = 0
ubyte newy = 0
vtui.initialize()
;vtui.screen_set(2)
vtui.gotoxy(30, 32)
vtui.print_str("arrow keys to move!", $61, 0)
vtui.gotoxy(0, 0)
vtui.save_rect(1, 1, $0000, 7, 7)
vtui.gotoxy(0, 0)
vtui.save_rect(1, 1, $0100, 7, 7)
vtui.print_str2("arrow keys to move!", $61, 0)
char_loop:
ubyte char = c64.GETIN()
@ -74,11 +96,11 @@ char_loop:
sub move_logo() {
vtui.gotoxy(xcoord, ycoord)
vtui.rest_rect(1, 1, $0100, 7, 7)
vtui.rest_rect($80, 1, $0100, 7, 7)
vtui.gotoxy(newx, newy)
vtui.save_rect(1, 1, $0100, 7, 7)
vtui.save_rect($80, 1, $0100, 7, 7)
vtui.gotoxy(newx, newy)
vtui.rest_rect(1, 1, $0000, 7, 7)
vtui.rest_rect($80, 1, $0000, 7, 7)
xcoord = newx
ycoord = newy
}
@ -89,7 +111,7 @@ char_loop:
vtui $1000 {
%asmbinary "VTUI0.6.BIN", 2 ; skip the 2 dummy load address bytes
%asmbinary "VTUI0.8.BIN", 2 ; skip the 2 dummy load address bytes
; NOTE: base address $1000 here must be the same as the block's memory address, for obvious reasons!
romsub $1000 = initialize() clobbers(A, X, Y)
@ -103,11 +125,24 @@ vtui $1000 {
romsub $1017 = scan_char() -> ubyte @A, ubyte @X
romsub $101a = hline(ubyte char @A, ubyte length @Y, ubyte colors @X) clobbers(A)
romsub $101d = vline(ubyte char @A, ubyte height @Y, ubyte colors @X) clobbers(A)
romsub $1020 = print_str(str string @R0, ubyte colors @X, ubyte convertchars @A) clobbers(A, Y)
romsub $1020 = print_str(str txtstring @R0, ubyte length @Y, ubyte colors @X, ubyte convertchars @A) clobbers(A, Y)
romsub $1023 = fill_box(ubyte char @A, ubyte width @R1, ubyte height @R2, ubyte colors @X) clobbers(A, Y)
romsub $1026 = pet2scr(ubyte char @A) -> ubyte @A
romsub $1029 = scr2pet(ubyte char @A) -> ubyte @A
romsub $102c = border(ubyte mode @A, ubyte width @R1, ubyte height @R2, ubyte colors @X) clobbers(Y) ; NOTE: mode 6 means 'custom' characters taken from r3 - r6
romsub $102f = save_rect(ubyte ramtype @A, ubyte vbank @Pc, uword address @R0, ubyte width @R1, ubyte height @R2) clobbers(A, X, Y)
romsub $1032 = rest_rect(ubyte ramtype @A, ubyte vbank @Pc, uword address @R0, ubyte width @R1, ubyte height @R2) clobbers(A, X, Y)
romsub $1035 = input_str(uword buffer @R0, ubyte buflen @Y, ubyte colors @X) clobbers (A) -> ubyte @Y
; -- helper function to do string length counting for you internally
asmsub print_str2(str txtstring @R0, ubyte colors @X, ubyte convertchars @A) clobbers(A, Y) {
%asm {{
pha
lda cx16.r0
ldy cx16.r0+1
jsr prog8_lib.strlen
pla
jmp print_str
}}
}
}

View File

@ -17,7 +17,7 @@ main {
irq {
const ubyte barheight = 4 ; should be big enough to re-trigger the Raster irq properly.
const ubyte barheight = 3 ; should be big enough to re-trigger the Raster irq properly.
ubyte[] colors = [6,2,4,5,15,7,1,13,3,12,8,11,9]
ubyte color = 0
ubyte yanim = 0

View File

@ -1,9 +1,24 @@
%import textio
%zeropage basicsafe
main {
sub start() {
txt.print("hello")
; str filename = "titlescreen.bin"
; ubyte success = cx16.vload(filename, 8, 0, $0000)
; if success {
; txt.print("load ok")
; cx16.VERA_DC_HSCALE = 64
; cx16.VERA_DC_VSCALE = 64
; cx16.VERA_L1_CONFIG = %00011111 ; 256c bitmap mode
; cx16.VERA_L1_MAPBASE = 0
; cx16.VERA_L1_TILEBASE = 0
; } else {
; txt.print("load fail")
; }
}
}

View File

@ -2,6 +2,7 @@
%import syslib
%zeropage basicsafe
spritedata $0a00 {
; this memory block contains the sprite data
; it must start on an address aligned to 64 bytes.

View File

@ -14,7 +14,7 @@
<keywords keywords="&amp;;-&gt;;@;\$;and;as;asmsub;break;clobbers;do;downto;else;false;for;goto;if;if_cc;if_cs;if_eq;if_mi;if_ne;if_neg;if_nz;if_pl;if_pos;if_vc;if_vs;if_z;in;inline;not;or;repeat;return;romsub;step;sub;to;true;until;when;while;xor;~" ignore_case="false" />
<keywords2 keywords="%address;%asm;%asmbinary;%asminclude;%breakpoint;%import;%launcher;%option;%output;%target;%zeropage;%zpreserved" />
<keywords3 keywords="byte;const;float;str;struct;ubyte;uword;void;word;zp" />
<keywords4 keywords="abs;acos;all;any;asin;atan;avg;ceil;cos;cos16;cos16u;cos8;cos8u;deg;fastrnd8;floor;len;ln;log2;lsb;lsl;lsr;max;memory;min;mkword;msb;offsetof;peek;peekw;poke;pokew;rad;reverse;rnd;rndf;rndw;rol;rol2;ror;ror2;round;sgn;sin;sin16;sin16u;sin8;sin8u;sizeof;sort;sqrt;sqrt16;sum;swap;tan" />
<keywords4 keywords="abs;acos;all;any;asin;atan;avg;ceil;cmp;cos;cos16;cos16u;cos8;cos8u;deg;fastrnd8;floor;len;ln;log2;lsb;lsl;lsr;max;memory;min;mkword;msb;offsetof;peek;peekw;poke;pokew;rad;reverse;rnd;rndf;rndw;rol;rol2;ror;ror2;round;sgn;sin;sin16;sin16u;sin8;sin8u;sizeof;sort;sqrt;sqrt16;sum;swap;tan" />
</highlighting>
<extensionMap>
<mapping ext="p8" />

109
syntax-files/Vim/prog8.vim Normal file
View File

@ -0,0 +1,109 @@
" Vim syntax file
" Language: Prog8
" Maintainer: Elektron72
" Latest Revision: 23 March 2021
if exists("b:current_syntax")
finish
endif
syn match prog8Comment ";.*$"
syn region prog8String start=+@\?"+ skip=+\\"+ end=+"+
syn region prog8Character start=+@\?'+ skip=+\\'+ end=+'+
syn match prog8Number "\<\d\+\>"
syn match prog8Number "$\x\+\>"
syn match prog8Number "%[01]\+\>"
syn keyword prog8Boolean true false
syn match prog8Float "\<\d\+\.\d\+\([eE]\d\+\)\?\>"
syn region prog8Expression matchgroup=prog8AddressOp start="@(" end=")"
\ transparent
syn match prog8Function "\(\<\(asm\)\?sub\>\s\+\)\@16<=\<\w\+\>"
syn match prog8Function "\(romsub\s\+$\x\+\s\+=\s\+\)\@16<=\<\w\+\>"
syn keyword prog8Statement break goto return asmsub sub inline
syn match prog8Statement "\<\(asm\|rom\)\?sub\>"
syn keyword prog8Conditional if else when
syn keyword prog8Conditional if_cs if_cc if_vs if_vc if_eq if_z if_ne if_nz
syn keyword prog8Conditional if_pl if_pos if_mi if_neg
syn keyword prog8Conditional when
syn keyword prog8Repeat for while in do until repeat
syn match prog8Label "\<\w\+\>:"
syn keyword prog8Operator and or to downto as void
syn match prog8Directive "\(^\|\s\)%\(target\|output\|launcher\|zeropage\)\>"
syn match prog8Directive "\(^\|\s\)%\(zpreserved\|address\|import\|option\)\>"
syn match prog8Directive "\(^\|\s\)%\(asmbinary\|asminclude\|breakpoint\)\>"
syn match prog8Directive "\(^\|\s\)%asm\>"
syn match prog8Type "\<\%(u\?byte\|u\?word\|float\|str\)\>"
syn region prog8ArrayType matchgroup=prog8Type
\ start="\<\%(u\?byte\|u\?word\|float\|str\)\[" end="\]"
\ transparent
syn keyword prog8StorageClass const
syn match prog8StorageClass "\(^\|\s\)@zp\>"
syn keyword prog8Structure struct
syn region prog8Block start="{" end="}" transparent
syn region prog8Expression start="(" end=")" transparent
syn region prog8Array start="\[" end="\]" transparent
if !exists("g:prog8_no_highlight_builtins")
runtime! syntax/prog8_builtins.vim
endif
syn region prog8Asm start="\(%asm\)\@16<=\s\+{{" end="}}" contains=
\prog8Comment,
\prog8Character,
\prog8Number,
\prog8AsmIdentifier,
\prog8AsmStatement,
\prog8AsmLabel,
\prog8BuiltInVar,
\prog8BuiltInFunc
syn sync match prog8AsmSync groupthere prog8Asm "%asm\s\+{{"
syn keyword prog8AsmIdentifier a x y contained
syn keyword prog8AsmStatement adc and asl bbr bbs bcc bcs beq bit bmi contained
syn keyword prog8AsmStatement bne bpl bra brk bvc bvs clc cld cli clv contained
syn keyword prog8AsmStatement cmp cpx cpy dec dex dey eor inc inx iny contained
syn keyword prog8AsmStatement jmp jsr lda ldx ldy lsr nop ora pha php contained
syn keyword prog8AsmStatement phx phy pla plp plx ply rmb rol ror rti contained
syn keyword prog8AsmStatement rts sbc sec sed sei smb sta stp stx sty contained
syn keyword prog8AsmStatement stz tax tay trb tsb tsx txa txs tya wai contained
syn match prog8AsmLabel "^\([-+]\|\(\w\+\.\)*\w\+\)" contained
hi def link prog8Comment Comment
hi def link prog8String String
hi def link prog8Character Character
hi def link prog8Number Number
hi def link prog8Boolean Boolean
hi def link prog8Float Float
hi def link prog8AddressOp Identifier
hi def link prog8Function Function
hi def link prog8Statement Statement
hi def link prog8Conditional Conditional
hi def link prog8Repeat Repeat
hi def link prog8Label Label
hi def link prog8Operator Operator
hi def link prog8Directive PreProc
hi def link prog8Type Type
hi def link prog8StorageClass StorageClass
hi def link prog8Structure Structure
hi def link prog8AsmIdentifier Identifier
hi def link prog8AsmStatement Statement
hi def link prog8AsmLabel Label

View File

@ -0,0 +1,820 @@
" Vim syntax file
" Language: Prog8 (built-in functions)
" Maintainer: Elektron72
" Latest Revision: 23 March 2021
" Built-in functions
" Math functions
syn keyword prog8BuiltInFunc abs atan ceil cos cos8u cos8 cos16u cos16 deg floor
syn keyword prog8BuiltInFunc ln log2 rad round sin sgn sin8u sin8 sin16u sin16
syn keyword prog8BuiltInFunc sqrt16 sqrt tan
" Array functions
syn keyword prog8BuiltInFunc any all len max min reverse sum sort
" Miscellaneous functions
syn keyword prog8BuiltInFunc cmp lsb msb mkword peek peekw poke pokew rnd rndw
syn keyword prog8BuiltInFunc rndf fastrnd8 rol rol2 ror ror2 sizeof offsetof
syn keyword prog8BuiltInFunc swap memory
" c64/floats.p8
syn match prog8BuiltInVar "\<floats\.PI\>"
syn match prog8BuiltInVar "\<floats\.TWOPI\>"
syn match prog8BuiltInFunc "\<floats\.MOVFM\>"
syn match prog8BuiltInFunc "\<floats\.FREADMEM\>"
syn match prog8BuiltInFunc "\<floats\.CONUPK\>"
syn match prog8BuiltInFunc "\<floats\.FAREADMEM\>"
syn match prog8BuiltInFunc "\<floats\.MOVFA\>"
syn match prog8BuiltInFunc "\<floats\.MOVAF\>"
syn match prog8BuiltInFunc "\<floats\.MOVEF\>"
syn match prog8BuiltInFunc "\<floats\.MOVMF\>"
syn match prog8BuiltInFunc "\<floats\.FTOSWORDYA\>"
syn match prog8BuiltInFunc "\<floats\.GETADR\>"
syn match prog8BuiltInFunc "\<floats\.QINT\>"
syn match prog8BuiltInFunc "\<floats\.AYINT\>"
syn match prog8BuiltInFunc "\<floats\.GIVAYF\>"
syn match prog8BuiltInFunc "\<floats\.FREADUY\>"
syn match prog8BuiltInFunc "\<floats\.FREADSA\>"
syn match prog8BuiltInFunc "\<floats\.FREADSTR\>"
syn match prog8BuiltInFunc "\<floats\.FPRINTLN\>"
syn match prog8BuiltInFunc "\<floats\.FOUT\>"
syn match prog8BuiltInFunc "\<floats\.FADDH\>"
syn match prog8BuiltInFunc "\<floats\.MUL10\>"
syn match prog8BuiltInFunc "\<floats\.DIV10\>"
syn match prog8BuiltInFunc "\<floats\.FCOMP\>"
syn match prog8BuiltInFunc "\<floats\.FADDT\>"
syn match prog8BuiltInFunc "\<floats\.FADD\>"
syn match prog8BuiltInFunc "\<floats\.FSUBT\>"
syn match prog8BuiltInFunc "\<floats\.FSUB\>"
syn match prog8BuiltInFunc "\<floats\.FMULTT\>"
syn match prog8BuiltInFunc "\<floats\.FMULT\>"
syn match prog8BuiltInFunc "\<floats\.FDIVT\>"
syn match prog8BuiltInFunc "\<floats\.FDIV\>"
syn match prog8BuiltInFunc "\<floats\.FPWRT\>"
syn match prog8BuiltInFunc "\<floats\.FPWR\>"
syn match prog8BuiltInFunc "\<floats\.FINLOG\>"
syn match prog8BuiltInFunc "\<floats\.NOTOP\>"
syn match prog8BuiltInFunc "\<floats\.INT\>"
syn match prog8BuiltInFunc "\<floats\.LOG\>"
syn match prog8BuiltInFunc "\<floats\.SGN\>"
syn match prog8BuiltInFunc "\<floats\.SIGN\>"
syn match prog8BuiltInFunc "\<floats\.ABS\>"
syn match prog8BuiltInFunc "\<floats\.SQR\>"
syn match prog8BuiltInFunc "\<floats\.SQRA\>"
syn match prog8BuiltInFunc "\<floats\.EXP\>"
syn match prog8BuiltInFunc "\<floats\.NEGOP\>"
syn match prog8BuiltInFunc "\<floats\.RND\>"
syn match prog8BuiltInFunc "\<floats\.COS\>"
syn match prog8BuiltInFunc "\<floats\.SIN\>"
syn match prog8BuiltInFunc "\<floats\.TAN\>"
syn match prog8BuiltInFunc "\<floats\.ATN\>"
syn match prog8BuiltInFunc "\<floats\.FREADS32\>"
syn match prog8BuiltInFunc "\<floats\.FREADUS32\>"
syn match prog8BuiltInFunc "\<floats\.FREADS24AXY\>"
syn match prog8BuiltInFunc "\<floats\.GIVUAYFAY\>"
syn match prog8BuiltInFunc "\<floats\.GIVAFAY\>"
syn match prog8BuiltInFunc "\<floats\.FTOSWRDAY\>"
syn match prog8BuiltInFunc "\<floats\.GETADRAY\>"
syn match prog8BuiltInFunc "\<floats\.print_f\>"
" c64/graphics.p8
syn match prog8BuiltInVar "\<graphics\.BITMAP_ADDRESS\>"
syn match prog8BuiltInVar "\<graphics\.WIDTH\>"
syn match prog8BuiltInVar "\<graphics\.HEIGHT\>"
syn match prog8BuiltInFunc "\<graphics\.enable_bitmap_mode\>"
syn match prog8BuiltInFunc "\<graphics\.disable_bitmap_mode\>"
syn match prog8BuiltInFunc "\<graphics\.clear_screen\>"
syn match prog8BuiltInFunc "\<graphics\.line\>"
syn match prog8BuiltInFunc "\<graphics\.rect\>"
syn match prog8BuiltInFunc "\<graphics\.fillrect\>"
syn match prog8BuiltInFunc "\<graphics\.horizontal_line\>"
syn match prog8BuiltInFunc "\<graphics\.vertical_line\>"
syn match prog8BuiltInFunc "\<graphics\.circle\>"
syn match prog8BuiltInFunc "\<graphics\.disc\>"
syn match prog8BuiltInFunc "\<graphics\.plot\>"
" c64/syslib.p8
syn match prog8BuiltInVar "\<c64\.TIME_HI\>"
syn match prog8BuiltInVar "\<c64\.TIME_MID\>"
syn match prog8BuiltInVar "\<c64\.TIME_LO\>"
syn match prog8BuiltInVar "\<c64\.STATUS\>"
syn match prog8BuiltInVar "\<c64\.STKEY\>"
syn match prog8BuiltInVar "\<c64\.SFDX\>"
syn match prog8BuiltInVar "\<c64\.COLOR\>"
syn match prog8BuiltInVar "\<c64\.HIBASE\>"
syn match prog8BuiltInVar "\<c64\.CINV\>"
syn match prog8BuiltInVar "\<c64\.NMI_VEC\>"
syn match prog8BuiltInVar "\<c64\.RESET_VEC\>"
syn match prog8BuiltInVar "\<c64\.IRQ_VEC\>"
syn match prog8BuiltInVar "\<c64\.SPRPTR0\>"
syn match prog8BuiltInVar "\<c64\.SPRPTR1\>"
syn match prog8BuiltInVar "\<c64\.SPRPTR2\>"
syn match prog8BuiltInVar "\<c64\.SPRPTR3\>"
syn match prog8BuiltInVar "\<c64\.SPRPTR4\>"
syn match prog8BuiltInVar "\<c64\.SPRPTR5\>"
syn match prog8BuiltInVar "\<c64\.SPRPTR6\>"
syn match prog8BuiltInVar "\<c64\.SPRPTR7\>"
syn match prog8BuiltInVar "\<c64\.SPRPTR\>"
syn match prog8BuiltInVar "\<c64\.SP0X\>"
syn match prog8BuiltInVar "\<c64\.SP0Y\>"
syn match prog8BuiltInVar "\<c64\.SP1X\>"
syn match prog8BuiltInVar "\<c64\.SP1Y\>"
syn match prog8BuiltInVar "\<c64\.SP2X\>"
syn match prog8BuiltInVar "\<c64\.SP2Y\>"
syn match prog8BuiltInVar "\<c64\.SP3X\>"
syn match prog8BuiltInVar "\<c64\.SP3Y\>"
syn match prog8BuiltInVar "\<c64\.SP4X\>"
syn match prog8BuiltInVar "\<c64\.SP4Y\>"
syn match prog8BuiltInVar "\<c64\.SP5X\>"
syn match prog8BuiltInVar "\<c64\.SP5Y\>"
syn match prog8BuiltInVar "\<c64\.SP6X\>"
syn match prog8BuiltInVar "\<c64\.SP6Y\>"
syn match prog8BuiltInVar "\<c64\.SP7X\>"
syn match prog8BuiltInVar "\<c64\.SP7Y\>"
syn match prog8BuiltInVar "\<c64\.SPXY\>"
syn match prog8BuiltInVar "\<c64\.SPXYW\>"
syn match prog8BuiltInVar "\<c64\.MSIGX\>"
syn match prog8BuiltInVar "\<c64\.SCROLY\>"
syn match prog8BuiltInVar "\<c64\.RASTER\>"
syn match prog8BuiltInVar "\<c64\.LPENX\>"
syn match prog8BuiltInVar "\<c64\.LPENY\>"
syn match prog8BuiltInVar "\<c64\.SPENA\>"
syn match prog8BuiltInVar "\<c64\.SCROLX\>"
syn match prog8BuiltInVar "\<c64\.YXPAND\>"
syn match prog8BuiltInVar "\<c64\.VMCSB\>"
syn match prog8BuiltInVar "\<c64\.VICIRQ\>"
syn match prog8BuiltInVar "\<c64\.IREQMASK\>"
syn match prog8BuiltInVar "\<c64\.SPBGPR\>"
syn match prog8BuiltInVar "\<c64\.SPMC\>"
syn match prog8BuiltInVar "\<c64\.XXPAND\>"
syn match prog8BuiltInVar "\<c64\.SPSPCL\>"
syn match prog8BuiltInVar "\<c64\.SPBGCL\>"
syn match prog8BuiltInVar "\<c64\.EXTCOL\>"
syn match prog8BuiltInVar "\<c64\.BGCOL0\>"
syn match prog8BuiltInVar "\<c64\.BGCOL1\>"
syn match prog8BuiltInVar "\<c64\.BGCOL2\>"
syn match prog8BuiltInVar "\<c64\.BGCOL4\>"
syn match prog8BuiltInVar "\<c64\.SPMC0\>"
syn match prog8BuiltInVar "\<c64\.SPMC1\>"
syn match prog8BuiltInVar "\<c64\.SP0COL\>"
syn match prog8BuiltInVar "\<c64\.SP1COL\>"
syn match prog8BuiltInVar "\<c64\.SP2COL\>"
syn match prog8BuiltInVar "\<c64\.SP3COL\>"
syn match prog8BuiltInVar "\<c64\.SP4COL\>"
syn match prog8BuiltInVar "\<c64\.SP5COL\>"
syn match prog8BuiltInVar "\<c64\.SP6COL\>"
syn match prog8BuiltInVar "\<c64\.SP7COL\>"
syn match prog8BuiltInVar "\<c64\.SPCOL\>"
syn match prog8BuiltInVar "\<c64\.CIA1PRA\>"
syn match prog8BuiltInVar "\<c64\.CIA1PRB\>"
syn match prog8BuiltInVar "\<c64\.CIA1DDRA\>"
syn match prog8BuiltInVar "\<c64\.CIA1DDRB\>"
syn match prog8BuiltInVar "\<c64\.CIA1TAL\>"
syn match prog8BuiltInVar "\<c64\.CIA1TAH\>"
syn match prog8BuiltInVar "\<c64\.CIA1TBL\>"
syn match prog8BuiltInVar "\<c64\.CIA1TBH\>"
syn match prog8BuiltInVar "\<c64\.CIA1TOD10\>"
syn match prog8BuiltInVar "\<c64\.CIA1TODHR\>"
syn match prog8BuiltInVar "\<c64\.CIA1SDR\>"
syn match prog8BuiltInVar "\<c64\.CIA1ICR\>"
syn match prog8BuiltInVar "\<c64\.CIA1CRA\>"
syn match prog8BuiltInVar "\<c64\.CIA1CRB\>"
syn match prog8BuiltInVar "\<c64\.CIA2PRA\>"
syn match prog8BuiltInVar "\<c64\.CIA2PRB\>"
syn match prog8BuiltInVar "\<c64\.CIA2DDRA\>"
syn match prog8BuiltInVar "\<c64\.CIA2DDRB\>"
syn match prog8BuiltInVar "\<c64\.CIA2TAL\>"
syn match prog8BuiltInVar "\<c64\.CIA2TAH\>"
syn match prog8BuiltInVar "\<c64\.CIA2TBL\>"
syn match prog8BuiltInVar "\<c64\.CIA2TBH\>"
syn match prog8BuiltInVar "\<c64\.CIA2TOD10\>"
syn match prog8BuiltInVar "\<c64\.CIA2TODHR\>"
syn match prog8BuiltInVar "\<c64\.CIA2SDR\>"
syn match prog8BuiltInVar "\<c64\.CIA2ICR\>"
syn match prog8BuiltInVar "\<c64\.CIA2CRA\>"
syn match prog8BuiltInVar "\<c64\.CIA2CRB\>"
syn match prog8BuiltInVar "\<c64\.FREQLO1\>"
syn match prog8BuiltInVar "\<c64\.FREQHI1\>"
syn match prog8BuiltInVar "\<c64\.FREQ1\>"
syn match prog8BuiltInVar "\<c64\.PWLO1\>"
syn match prog8BuiltInVar "\<c64\.PWHI1\>"
syn match prog8BuiltInVar "\<c64\.PW1\>"
syn match prog8BuiltInVar "\<c64\.CR1\>"
syn match prog8BuiltInVar "\<c64\.AD1\>"
syn match prog8BuiltInVar "\<c64\.SR1\>"
syn match prog8BuiltInVar "\<c64\.FREQLO2\>"
syn match prog8BuiltInVar "\<c64\.FREQHI2\>"
syn match prog8BuiltInVar "\<c64\.FREQ2\>"
syn match prog8BuiltInVar "\<c64\.PWLO2\>"
syn match prog8BuiltInVar "\<c64\.PWHI2\>"
syn match prog8BuiltInVar "\<c64\.PW2\>"
syn match prog8BuiltInVar "\<c64\.CR2\>"
syn match prog8BuiltInVar "\<c64\.AD2\>"
syn match prog8BuiltInVar "\<c64\.SR2\>"
syn match prog8BuiltInVar "\<c64\.FREQLO3\>"
syn match prog8BuiltInVar "\<c64\.FREQHI3\>"
syn match prog8BuiltInVar "\<c64\.FREQ3\>"
syn match prog8BuiltInVar "\<c64\.PWLO3\>"
syn match prog8BuiltInVar "\<c64\.PWHI3\>"
syn match prog8BuiltInVar "\<c64\.PW3\>"
syn match prog8BuiltInVar "\<c64\.CR3\>"
syn match prog8BuiltInVar "\<c64\.AD3\>"
syn match prog8BuiltInVar "\<c64\.SR3\>"
syn match prog8BuiltInVar "\<c64\.FCLO\>"
syn match prog8BuiltInVar "\<c64\.FCHI\>"
syn match prog8BuiltInVar "\<c64\.FC\>"
syn match prog8BuiltInVar "\<c64\.RESFILT\>"
syn match prog8BuiltInVar "\<c64\.MVOL\>"
syn match prog8BuiltInVar "\<c64\.POTX\>"
syn match prog8BuiltInVar "\<c64\.POTY\>"
syn match prog8BuiltInVar "\<c64\.OSC3\>"
syn match prog8BuiltInVar "\<c64\.ENV3\>"
syn match prog8BuiltInFunc "\<c64\.STROUT\>"
syn match prog8BuiltInFunc "\<c64\.CLEARSCR\>"
syn match prog8BuiltInFunc "\<c64\.HOMECRSR\>"
syn match prog8BuiltInFunc "\<c64\.IRQDFRT\>"
syn match prog8BuiltInFunc "\<c64\.IRQDFEND\>"
syn match prog8BuiltInFunc "\<c64\.CINT\>"
syn match prog8BuiltInFunc "\<c64\.IOINIT\>"
syn match prog8BuiltInFunc "\<c64\.RAMTAS\>"
syn match prog8BuiltInFunc "\<c64\.RESTOR\>"
syn match prog8BuiltInFunc "\<c64\.VECTOR\>"
syn match prog8BuiltInFunc "\<c64\.SETMSG\>"
syn match prog8BuiltInFunc "\<c64\.SECOND\>"
syn match prog8BuiltInFunc "\<c64\.TKSA\>"
syn match prog8BuiltInFunc "\<c64\.MEMTOP\>"
syn match prog8BuiltInFunc "\<c64\.MEMBOT\>"
syn match prog8BuiltInFunc "\<c64\.SCNKEY\>"
syn match prog8BuiltInFunc "\<c64\.SETTMO\>"
syn match prog8BuiltInFunc "\<c64\.ACPTR\>"
syn match prog8BuiltInFunc "\<c64\.CIOUT\>"
syn match prog8BuiltInFunc "\<c64\.UNTLK\>"
syn match prog8BuiltInFunc "\<c64\.UNLSN\>"
syn match prog8BuiltInFunc "\<c64\.LISTEN\>"
syn match prog8BuiltInFunc "\<c64\.TALK\>"
syn match prog8BuiltInFunc "\<c64\.READST\>"
syn match prog8BuiltInFunc "\<c64\.SETLFS\>"
syn match prog8BuiltInFunc "\<c64\.SETNAM\>"
syn match prog8BuiltInFunc "\<c64\.OPEN\>"
syn match prog8BuiltInFunc "\<c64\.CLOSE\>"
syn match prog8BuiltInFunc "\<c64\.CHKIN\>"
syn match prog8BuiltInFunc "\<c64\.CHKOUT\>"
syn match prog8BuiltInFunc "\<c64\.CLRCHN\>"
syn match prog8BuiltInFunc "\<c64\.CHRIN\>"
syn match prog8BuiltInFunc "\<c64\.CHROUT\>"
syn match prog8BuiltInFunc "\<c64\.LOAD\>"
syn match prog8BuiltInFunc "\<c64\.SAVE\>"
syn match prog8BuiltInFunc "\<c64\.SETTIM\>"
syn match prog8BuiltInFunc "\<c64\.RDTIM\>"
syn match prog8BuiltInFunc "\<c64\.STOP\>"
syn match prog8BuiltInFunc "\<c64\.GETIN\>"
syn match prog8BuiltInFunc "\<c64\.CLALL\>"
syn match prog8BuiltInFunc "\<c64\.UDTIM\>"
syn match prog8BuiltInFunc "\<c64\.SCREEN\>"
syn match prog8BuiltInFunc "\<c64\.PLOT\>"
syn match prog8BuiltInFunc "\<c64\.IOBASE\>"
syn match prog8BuiltInFunc "\<c64\.STOP2\>"
syn match prog8BuiltInFunc "\<c64\.RDTIM16\>"
syn match prog8BuiltInFunc "\<c64\.init_system\>"
syn match prog8BuiltInFunc "\<c64\.init_system_phase2\>"
syn match prog8BuiltInFunc "\<c64\.disable_runstop_and_charsetswitch\>"
syn match prog8BuiltInFunc "\<c64\.set_irq\>"
syn match prog8BuiltInFunc "\<c64\.restore_irq\>"
syn match prog8BuiltInFunc "\<c64\.set_rasterirq\>"
syn match prog8BuiltInVar "\<sys\.target\>"
syn match prog8BuiltInFunc "\<sys\.reset_system\>"
syn match prog8BuiltInFunc "\<sys\.wait\>"
syn match prog8BuiltInFunc "\<sys\.memcopy\>"
syn match prog8BuiltInFunc "\<sys\.memset\>"
syn match prog8BuiltInFunc "\<sys\.memsetw\>"
syn match prog8BuiltInFunc "\<sys\.rsave\>"
syn match prog8BuiltInFunc "\<sys\.rrestore\>"
syn match prog8BuiltInFunc "\<sys\.read_flags\>"
syn match prog8BuiltInFunc "\<sys\.clear_carry\>"
syn match prog8BuiltInFunc "\<sys\.set_carry\>"
syn match prog8BuiltInFunc "\<sys\.clear_irqd\>"
syn match prog8BuiltInFunc "\<sys\.set_irqd\>"
syn match prog8BuiltInFunc "\<sys\.exit\>"
syn match prog8BuiltInFunc "\<sys\.progend\>"
syn match prog8BuiltInVar "\<cx16\.r0\>"
syn match prog8BuiltInVar "\<cx16\.r1\>"
syn match prog8BuiltInVar "\<cx16\.r2\>"
syn match prog8BuiltInVar "\<cx16\.r3\>"
syn match prog8BuiltInVar "\<cx16\.r4\>"
syn match prog8BuiltInVar "\<cx16\.r5\>"
syn match prog8BuiltInVar "\<cx16\.r6\>"
syn match prog8BuiltInVar "\<cx16\.r7\>"
syn match prog8BuiltInVar "\<cx16\.r8\>"
syn match prog8BuiltInVar "\<cx16\.r9\>"
syn match prog8BuiltInVar "\<cx16\.r10\>"
syn match prog8BuiltInVar "\<cx16\.r11\>"
syn match prog8BuiltInVar "\<cx16\.r12\>"
syn match prog8BuiltInVar "\<cx16\.r13\>"
syn match prog8BuiltInVar "\<cx16\.r14\>"
syn match prog8BuiltInVar "\<cx16\.r15\>"
" c64/textio.p8
syn match prog8BuiltInVar "\<txt\.DEFAULT_WIDTH\>"
syn match prog8BuiltInVar "\<txt\.DEFAULT_HEIGHT\>"
syn match prog8BuiltInFunc "\<txt\.clear_screen\>"
syn match prog8BuiltInFunc "\<txt\.home\>"
syn match prog8BuiltInFunc "\<txt\.nl\>"
syn match prog8BuiltInFunc "\<txt\.spc\>"
syn match prog8BuiltInFunc "\<txt\.column\>"
syn match prog8BuiltInFunc "\<txt\.fill_screen\>"
syn match prog8BuiltInFunc "\<txt\.clear_screenchars\>"
syn match prog8BuiltInFunc "\<txt\.clear_screencolors\>"
syn match prog8BuiltInFunc "\<txt\.color\>"
syn match prog8BuiltInFunc "\<txt\.lowercase\>"
syn match prog8BuiltInFunc "\<txt\.uppercase\>"
syn match prog8BuiltInFunc "\<txt\.scroll_left\>"
syn match prog8BuiltInFunc "\<txt\.scroll_right\>"
syn match prog8BuiltInFunc "\<txt\.scroll_up\>"
syn match prog8BuiltInFunc "\<txt\.scroll_down\>"
syn match prog8BuiltInFunc "\<txt\.chrout\>"
syn match prog8BuiltInFunc "\<txt\.print\>"
syn match prog8BuiltInFunc "\<txt\.print_ub0\>"
syn match prog8BuiltInFunc "\<txt\.print_ub\>"
syn match prog8BuiltInFunc "\<txt\.print_b\>"
syn match prog8BuiltInFunc "\<txt\.print_ubhex\>"
syn match prog8BuiltInFunc "\<txt\.print_ubbin\>"
syn match prog8BuiltInFunc "\<txt\.print_uwbin\>"
syn match prog8BuiltInFunc "\<txt\.print_uwhex\>"
syn match prog8BuiltInFunc "\<txt\.print_uw0\>"
syn match prog8BuiltInFunc "\<txt\.print_uw\>"
syn match prog8BuiltInFunc "\<txt\.print_w\>"
syn match prog8BuiltInFunc "\<txt\.input_chars\>"
syn match prog8BuiltInFunc "\<txt\.setchr\>"
syn match prog8BuiltInFunc "\<txt\.getchr\>"
syn match prog8BuiltInFunc "\<txt\.setclr\>"
syn match prog8BuiltInFunc "\<txt\.getclr\>"
syn match prog8BuiltInFunc "\<txt\.setcc\>"
syn match prog8BuiltInFunc "\<txt\.plot\>"
syn match prog8BuiltInFunc "\<txt\.width\>"
syn match prog8BuiltInFunc "\<txt\.height\>"
" cx16/floats.p8
syn match prog8BuiltInVar "\<floats\.PI\>"
syn match prog8BuiltInVar "\<floats\.TWOPI\>"
syn match prog8BuiltInFunc "\<floats\.AYINT\>"
syn match prog8BuiltInFunc "\<floats\.GIVAYF\>"
syn match prog8BuiltInFunc "\<floats\.GETADR\>"
syn match prog8BuiltInFunc "\<floats\.FADDH\>"
syn match prog8BuiltInFunc "\<floats\.FSUB\>"
syn match prog8BuiltInFunc "\<floats\.FSUBT\>"
syn match prog8BuiltInFunc "\<floats\.FADD\>"
syn match prog8BuiltInFunc "\<floats\.FADDT\>"
syn match prog8BuiltInFunc "\<floats\.ZEROFC\>"
syn match prog8BuiltInFunc "\<floats\.NORMAL\>"
syn match prog8BuiltInFunc "\<floats\.LOG\>"
syn match prog8BuiltInFunc "\<floats\.FMULT\>"
syn match prog8BuiltInFunc "\<floats\.FMULTT\>"
syn match prog8BuiltInFunc "\<floats\.CONUPK\>"
syn match prog8BuiltInFunc "\<floats\.MUL10\>"
syn match prog8BuiltInFunc "\<floats\.DIV10\>"
syn match prog8BuiltInFunc "\<floats\.FDIV\>"
syn match prog8BuiltInFunc "\<floats\.FDIVT\>"
syn match prog8BuiltInFunc "\<floats\.MOVFM\>"
syn match prog8BuiltInFunc "\<floats\.MOVMF\>"
syn match prog8BuiltInFunc "\<floats\.MOVFA\>"
syn match prog8BuiltInFunc "\<floats\.MOVAF\>"
syn match prog8BuiltInFunc "\<floats\.MOVEF\>"
syn match prog8BuiltInFunc "\<floats\.SIGN\>"
syn match prog8BuiltInFunc "\<floats\.SGN\>"
syn match prog8BuiltInFunc "\<floats\.FREADSA\>"
syn match prog8BuiltInFunc "\<floats\.ABS\>"
syn match prog8BuiltInFunc "\<floats\.FCOMP\>"
syn match prog8BuiltInFunc "\<floats\.INT\>"
syn match prog8BuiltInFunc "\<floats\.FINLOG\>"
syn match prog8BuiltInFunc "\<floats\.FOUT\>"
syn match prog8BuiltInFunc "\<floats\.SQR\>"
syn match prog8BuiltInFunc "\<floats\.FPWRT\>"
syn match prog8BuiltInFunc "\<floats\.NEGOP\>"
syn match prog8BuiltInFunc "\<floats\.EXP\>"
syn match prog8BuiltInFunc "\<floats\.RND2\>"
syn match prog8BuiltInFunc "\<floats\.RND\>"
syn match prog8BuiltInFunc "\<floats\.COS\>"
syn match prog8BuiltInFunc "\<floats\.SIN\>"
syn match prog8BuiltInFunc "\<floats\.TAN\>"
syn match prog8BuiltInFunc "\<floats\.ATN\>"
syn match prog8BuiltInFunc "\<floats\.GIVUAYFAY\>"
syn match prog8BuiltInFunc "\<floats\.GIVAYFAY\>"
syn match prog8BuiltInFunc "\<floats\.FTOSWRDAY\>"
syn match prog8BuiltInFunc "\<floats\.GETADRAY\>"
syn match prog8BuiltInFunc "\<floats\.FREADUY\>"
syn match prog8BuiltInFunc "\<floats\.h\>"
" cx16/gfx2.p8
syn match prog8BuiltInVar "\<gfx2\.active_mode\>"
syn match prog8BuiltInVar "\<gfx2\.width\>"
syn match prog8BuiltInVar "\<gfx2\.height\>"
syn match prog8BuiltInVar "\<gfx2\.bpp\>"
syn match prog8BuiltInVar "\<gfx2\.monochrome_dont_stipple_flag\>"
syn match prog8BuiltInFunc "\<gfx2\.screen_mode\>"
syn match prog8BuiltInFunc "\<gfx2\.clear_screen\>"
syn match prog8BuiltInFunc "\<gfx2\.monochrome_stipple\>"
syn match prog8BuiltInFunc "\<gfx2\.rect\>"
syn match prog8BuiltInFunc "\<gfx2\.fillrect\>"
syn match prog8BuiltInFunc "\<gfx2\.horizontal_line\>"
syn match prog8BuiltInFunc "\<gfx2\.vertical_line\>"
syn match prog8BuiltInFunc "\<gfx2\.line\>"
syn match prog8BuiltInFunc "\<gfx2\.circle\>"
syn match prog8BuiltInFunc "\<gfx2\.disc\>"
syn match prog8BuiltInFunc "\<gfx2\.plot\>"
syn match prog8BuiltInFunc "\<gfx2\.position\>"
syn match prog8BuiltInFunc "\<gfx2\.next_pixel\>"
syn match prog8BuiltInFunc "\<gfx2\.next_pixels\>"
syn match prog8BuiltInFunc "\<gfx2\.set_8_pixels_from_bits\>"
syn match prog8BuiltInVar "\<gfx2\.charset_orig_bank\>"
syn match prog8BuiltInVar "\<gfx2\.charset_orig_addr\>"
syn match prog8BuiltInVar "\<gfx2\.charset_bank\>"
syn match prog8BuiltInVar "\<gfx2\.charset_addr\>"
syn match prog8BuiltInFunc "\<gfx2\.text_charset\>"
syn match prog8BuiltInFunc "\<gfx2\.text\>"
syn match prog8BuiltInFunc "\<gfx2\.cs_innerloop640\>"
syn match prog8BuiltInFunc "\<gfx2\.addr_mul_24_for_highres_4c\>"
syn match prog8BuiltInFunc "\<gfx2\.addr_mul_24_for_lores_256c\>"
" cx16/graphics.p8
syn match prog8BuiltInVar "\<graphics\.WIDTH\>"
syn match prog8BuiltInVar "\<graphics\.HEIGHT\>"
syn match prog8BuiltInFunc "\<graphics\.enable_bitmap_mode\>"
syn match prog8BuiltInFunc "\<graphics\.disable_bitmap_mode\>"
syn match prog8BuiltInFunc "\<graphics\.clear_screen\>"
syn match prog8BuiltInFunc "\<graphics\.line\>"
syn match prog8BuiltInFunc "\<graphics\.fillrect\>"
syn match prog8BuiltInFunc "\<graphics\.rect\>"
syn match prog8BuiltInFunc "\<graphics\.horizontal_line\>"
syn match prog8BuiltInFunc "\<graphics\.vertical_line\>"
syn match prog8BuiltInFunc "\<graphics\.circle\>"
syn match prog8BuiltInFunc "\<graphics\.disc\>"
syn match prog8BuiltInFunc "\<graphics\.plot\>"
" cx16/palette.p8
syn match prog8BuiltInVar "\<palette\.vera_palette_ptr\>"
syn match prog8BuiltInVar "\<palette\.c\>"
syn match prog8BuiltInFunc "\<palette\.set_color\>"
syn match prog8BuiltInFunc "\<palette\.set_rgb4\>"
syn match prog8BuiltInFunc "\<palette\.set_rgb\>"
syn match prog8BuiltInFunc "\<palette\.set_rgb8\>"
syn match prog8BuiltInFunc "\<palette\.set_monochrome\>"
syn match prog8BuiltInFunc "\<palette\.set_grayscale\>"
syn match prog8BuiltInVar "\<palette\.C64_colorpalette_dark\>"
syn match prog8BuiltInVar "\<palette\.C64_colorpalette_pepto\>"
syn match prog8BuiltInVar "\<palette\.C64_colorpalette_light\>"
syn match prog8BuiltInFunc "\<palette\.set_c64pepto\>"
syn match prog8BuiltInFunc "\<palette\.set_c64light\>"
syn match prog8BuiltInFunc "\<palette\.set_c64dark\>"
" cx16/syslib.p8
syn match prog8BuiltInFunc "\<c64\.CINT\>"
syn match prog8BuiltInFunc "\<c64\.IOINIT\>"
syn match prog8BuiltInFunc "\<c64\.RAMTAS\>"
syn match prog8BuiltInFunc "\<c64\.RESTOR\>"
syn match prog8BuiltInFunc "\<c64\.VECTOR\>"
syn match prog8BuiltInFunc "\<c64\.SETMSG\>"
syn match prog8BuiltInFunc "\<c64\.SECOND\>"
syn match prog8BuiltInFunc "\<c64\.TKSA\>"
syn match prog8BuiltInFunc "\<c64\.MEMTOP\>"
syn match prog8BuiltInFunc "\<c64\.MEMBOT\>"
syn match prog8BuiltInFunc "\<c64\.SCNKEY\>"
syn match prog8BuiltInFunc "\<c64\.SETTMO\>"
syn match prog8BuiltInFunc "\<c64\.ACPTR\>"
syn match prog8BuiltInFunc "\<c64\.CIOUT\>"
syn match prog8BuiltInFunc "\<c64\.UNTLK\>"
syn match prog8BuiltInFunc "\<c64\.UNLSN\>"
syn match prog8BuiltInFunc "\<c64\.LISTEN\>"
syn match prog8BuiltInFunc "\<c64\.TALK\>"
syn match prog8BuiltInFunc "\<c64\.READST\>"
syn match prog8BuiltInFunc "\<c64\.SETLFS\>"
syn match prog8BuiltInFunc "\<c64\.SETNAM\>"
syn match prog8BuiltInFunc "\<c64\.OPEN\>"
syn match prog8BuiltInFunc "\<c64\.CLOSE\>"
syn match prog8BuiltInFunc "\<c64\.CHKIN\>"
syn match prog8BuiltInFunc "\<c64\.CHKOUT\>"
syn match prog8BuiltInFunc "\<c64\.CLRCHN\>"
syn match prog8BuiltInFunc "\<c64\.CHRIN\>"
syn match prog8BuiltInFunc "\<c64\.CHROUT\>"
syn match prog8BuiltInFunc "\<c64\.LOAD\>"
syn match prog8BuiltInFunc "\<c64\.SAVE\>"
syn match prog8BuiltInFunc "\<c64\.SETTIM\>"
syn match prog8BuiltInFunc "\<c64\.RDTIM\>"
syn match prog8BuiltInFunc "\<c64\.STOP\>"
syn match prog8BuiltInFunc "\<c64\.GETIN\>"
syn match prog8BuiltInFunc "\<c64\.CLALL\>"
syn match prog8BuiltInFunc "\<c64\.UDTIM\>"
syn match prog8BuiltInFunc "\<c64\.SCREEN\>"
syn match prog8BuiltInFunc "\<c64\.PLOT\>"
syn match prog8BuiltInFunc "\<c64\.IOBASE\>"
syn match prog8BuiltInFunc "\<c64\.STOP2\>"
syn match prog8BuiltInFunc "\<c64\.RDTIM16\>"
syn match prog8BuiltInFunc "\<c64\.MEMTOP2\>"
syn match prog8BuiltInVar "\<cx16\.CINV\>"
syn match prog8BuiltInVar "\<cx16\.NMI_VEC\>"
syn match prog8BuiltInVar "\<cx16\.RESET_VEC\>"
syn match prog8BuiltInVar "\<cx16\.IRQ_VEC\>"
syn match prog8BuiltInVar "\<cx16\.r0\>"
syn match prog8BuiltInVar "\<cx16\.r1\>"
syn match prog8BuiltInVar "\<cx16\.r2\>"
syn match prog8BuiltInVar "\<cx16\.r3\>"
syn match prog8BuiltInVar "\<cx16\.r4\>"
syn match prog8BuiltInVar "\<cx16\.r5\>"
syn match prog8BuiltInVar "\<cx16\.r6\>"
syn match prog8BuiltInVar "\<cx16\.r7\>"
syn match prog8BuiltInVar "\<cx16\.r8\>"
syn match prog8BuiltInVar "\<cx16\.r9\>"
syn match prog8BuiltInVar "\<cx16\.r10\>"
syn match prog8BuiltInVar "\<cx16\.r11\>"
syn match prog8BuiltInVar "\<cx16\.r12\>"
syn match prog8BuiltInVar "\<cx16\.r13\>"
syn match prog8BuiltInVar "\<cx16\.r14\>"
syn match prog8BuiltInVar "\<cx16\.r15\>"
syn match prog8BuiltInVar "\<cx16\.VERA_BASE\>"
syn match prog8BuiltInVar "\<cx16\.VERA_ADDR_L\>"
syn match prog8BuiltInVar "\<cx16\.VERA_ADDR_M\>"
syn match prog8BuiltInVar "\<cx16\.VERA_ADDR_H\>"
syn match prog8BuiltInVar "\<cx16\.VERA_DATA0\>"
syn match prog8BuiltInVar "\<cx16\.VERA_DATA1\>"
syn match prog8BuiltInVar "\<cx16\.VERA_CTRL\>"
syn match prog8BuiltInVar "\<cx16\.VERA_IEN\>"
syn match prog8BuiltInVar "\<cx16\.VERA_ISR\>"
syn match prog8BuiltInVar "\<cx16\.VERA_IRQ_LINE_L\>"
syn match prog8BuiltInVar "\<cx16\.VERA_DC_VIDEO\>"
syn match prog8BuiltInVar "\<cx16\.VERA_DC_HSCALE\>"
syn match prog8BuiltInVar "\<cx16\.VERA_DC_VSCALE\>"
syn match prog8BuiltInVar "\<cx16\.VERA_DC_BORDER\>"
syn match prog8BuiltInVar "\<cx16\.VERA_DC_HSTART\>"
syn match prog8BuiltInVar "\<cx16\.VERA_DC_HSTOP\>"
syn match prog8BuiltInVar "\<cx16\.VERA_DC_VSTART\>"
syn match prog8BuiltInVar "\<cx16\.VERA_DC_VSTOP\>"
syn match prog8BuiltInVar "\<cx16\.VERA_L0_CONFIG\>"
syn match prog8BuiltInVar "\<cx16\.VERA_L0_MAPBASE\>"
syn match prog8BuiltInVar "\<cx16\.VERA_L0_TILEBASE\>"
syn match prog8BuiltInVar "\<cx16\.VERA_L0_HSCROLL_L\>"
syn match prog8BuiltInVar "\<cx16\.VERA_L0_HSCROLL_H\>"
syn match prog8BuiltInVar "\<cx16\.VERA_L0_VSCROLL_L\>"
syn match prog8BuiltInVar "\<cx16\.VERA_L0_VSCROLL_H\>"
syn match prog8BuiltInVar "\<cx16\.VERA_L1_CONFIG\>"
syn match prog8BuiltInVar "\<cx16\.VERA_L1_MAPBASE\>"
syn match prog8BuiltInVar "\<cx16\.VERA_L1_TILEBASE\>"
syn match prog8BuiltInVar "\<cx16\.VERA_L1_HSCROLL_L\>"
syn match prog8BuiltInVar "\<cx16\.VERA_L1_HSCROLL_H\>"
syn match prog8BuiltInVar "\<cx16\.VERA_L1_VSCROLL_L\>"
syn match prog8BuiltInVar "\<cx16\.VERA_L1_VSCROLL_H\>"
syn match prog8BuiltInVar "\<cx16\.VERA_AUDIO_CTRL\>"
syn match prog8BuiltInVar "\<cx16\.VERA_AUDIO_RATE\>"
syn match prog8BuiltInVar "\<cx16\.VERA_AUDIO_DATA\>"
syn match prog8BuiltInVar "\<cx16\.VERA_SPI_DATA\>"
syn match prog8BuiltInVar "\<cx16\.VERA_SPI_CTRL\>"
syn match prog8BuiltInVar "\<cx16\.via1\>"
syn match prog8BuiltInVar "\<cx16\.d1prb\>"
syn match prog8BuiltInVar "\<cx16\.d1pra\>"
syn match prog8BuiltInVar "\<cx16\.d1ddrb\>"
syn match prog8BuiltInVar "\<cx16\.d1ddra\>"
syn match prog8BuiltInVar "\<cx16\.d1t1l\>"
syn match prog8BuiltInVar "\<cx16\.d1t1h\>"
syn match prog8BuiltInVar "\<cx16\.d1t1ll\>"
syn match prog8BuiltInVar "\<cx16\.d1t1lh\>"
syn match prog8BuiltInVar "\<cx16\.d1t2l\>"
syn match prog8BuiltInVar "\<cx16\.d1t2h\>"
syn match prog8BuiltInVar "\<cx16\.d1sr\>"
syn match prog8BuiltInVar "\<cx16\.d1acr\>"
syn match prog8BuiltInVar "\<cx16\.d1pcr\>"
syn match prog8BuiltInVar "\<cx16\.d1ifr\>"
syn match prog8BuiltInVar "\<cx16\.d1ier\>"
syn match prog8BuiltInVar "\<cx16\.d1ora\>"
syn match prog8BuiltInVar "\<cx16\.via2\>"
syn match prog8BuiltInVar "\<cx16\.d2prb\>"
syn match prog8BuiltInVar "\<cx16\.d2pra\>"
syn match prog8BuiltInVar "\<cx16\.d2ddrb\>"
syn match prog8BuiltInVar "\<cx16\.d2ddra\>"
syn match prog8BuiltInVar "\<cx16\.d2t1l\>"
syn match prog8BuiltInVar "\<cx16\.d2t1h\>"
syn match prog8BuiltInVar "\<cx16\.d2t1ll\>"
syn match prog8BuiltInVar "\<cx16\.d2t1lh\>"
syn match prog8BuiltInVar "\<cx16\.d2t2l\>"
syn match prog8BuiltInVar "\<cx16\.d2t2h\>"
syn match prog8BuiltInVar "\<cx16\.d2sr\>"
syn match prog8BuiltInVar "\<cx16\.d2acr\>"
syn match prog8BuiltInVar "\<cx16\.d2pcr\>"
syn match prog8BuiltInVar "\<cx16\.d2ifr\>"
syn match prog8BuiltInVar "\<cx16\.d2ier\>"
syn match prog8BuiltInVar "\<cx16\.d2ora\>"
syn match prog8BuiltInFunc "\<cx16\.close_all\>"
syn match prog8BuiltInFunc "\<cx16\.lkupla\>"
syn match prog8BuiltInFunc "\<cx16\.lkupsa\>"
syn match prog8BuiltInFunc "\<cx16\.screen_set_mode\>"
syn match prog8BuiltInFunc "\<cx16\.screen_set_charset\>"
syn match prog8BuiltInFunc "\<cx16\.pfkey\>"
syn match prog8BuiltInFunc "\<cx16\.jsrfar\>"
syn match prog8BuiltInFunc "\<cx16\.fetch\>"
syn match prog8BuiltInFunc "\<cx16\.stash\>"
syn match prog8BuiltInFunc "\<cx16\.cmpare\>"
syn match prog8BuiltInFunc "\<cx16\.primm\>"
syn match prog8BuiltInFunc "\<cx16\.macptr\>"
syn match prog8BuiltInFunc "\<cx16\.enter_basic\>"
syn match prog8BuiltInFunc "\<cx16\.mouse_config\>"
syn match prog8BuiltInFunc "\<cx16\.mouse_get\>"
syn match prog8BuiltInFunc "\<cx16\.mouse_scan\>"
syn match prog8BuiltInFunc "\<cx16\.joystick_scan\>"
syn match prog8BuiltInFunc "\<cx16\.joystick_get\>"
syn match prog8BuiltInFunc "\<cx16\.clock_set_date_time\>"
syn match prog8BuiltInFunc "\<cx16\.clock_get_date_time\>"
syn match prog8BuiltInFunc "\<cx16\.GRAPH_init\>"
syn match prog8BuiltInFunc "\<cx16\.GRAPH_clear\>"
syn match prog8BuiltInFunc "\<cx16\.GRAPH_set_window\>"
syn match prog8BuiltInFunc "\<cx16\.GRAPH_set_colors\>"
syn match prog8BuiltInFunc "\<cx16\.GRAPH_draw_line\>"
syn match prog8BuiltInFunc "\<cx16\.GRAPH_draw_rect\>"
syn match prog8BuiltInFunc "\<cx16\.GRAPH_move_rect\>"
syn match prog8BuiltInFunc "\<cx16\.GRAPH_draw_oval\>"
syn match prog8BuiltInFunc "\<cx16\.GRAPH_draw_image\>"
syn match prog8BuiltInFunc "\<cx16\.GRAPH_set_font\>"
syn match prog8BuiltInFunc "\<cx16\.GRAPH_get_char_size\>"
syn match prog8BuiltInFunc "\<cx16\.GRAPH_put_char\>"
syn match prog8BuiltInFunc "\<cx16\.GRAPH_put_next_char\>"
syn match prog8BuiltInFunc "\<cx16\.FB_init\>"
syn match prog8BuiltInFunc "\<cx16\.FB_get_info\>"
syn match prog8BuiltInFunc "\<cx16\.FB_set_palette\>"
syn match prog8BuiltInFunc "\<cx16\.FB_cursor_position\>"
syn match prog8BuiltInFunc "\<cx16\.FB_cursor_position2\>"
syn match prog8BuiltInFunc "\<cx16\.FB_cursor_next_line\>"
syn match prog8BuiltInFunc "\<cx16\.FB_get_pixel\>"
syn match prog8BuiltInFunc "\<cx16\.FB_get_pixels\>"
syn match prog8BuiltInFunc "\<cx16\.FB_set_pixel\>"
syn match prog8BuiltInFunc "\<cx16\.FB_set_pixels\>"
syn match prog8BuiltInFunc "\<cx16\.FB_set_8_pixels\>"
syn match prog8BuiltInFunc "\<cx16\.FB_set_8_pixels_opaque\>"
syn match prog8BuiltInFunc "\<cx16\.FB_fill_pixels\>"
syn match prog8BuiltInFunc "\<cx16\.FB_filter_pixels\>"
syn match prog8BuiltInFunc "\<cx16\.FB_move_pixels\>"
syn match prog8BuiltInFunc "\<cx16\.sprite_set_image\>"
syn match prog8BuiltInFunc "\<cx16\.sprite_set_position\>"
syn match prog8BuiltInFunc "\<cx16\.memory_fill\>"
syn match prog8BuiltInFunc "\<cx16\.memory_copy\>"
syn match prog8BuiltInFunc "\<cx16\.memory_crc\>"
syn match prog8BuiltInFunc "\<cx16\.memory_decompress\>"
syn match prog8BuiltInFunc "\<cx16\.console_init\>"
syn match prog8BuiltInFunc "\<cx16\.console_put_char\>"
syn match prog8BuiltInFunc "\<cx16\.console_get_char\>"
syn match prog8BuiltInFunc "\<cx16\.console_put_image\>"
syn match prog8BuiltInFunc "\<cx16\.console_set_paging_message\>"
syn match prog8BuiltInFunc "\<cx16\.kbdbuf_put\>"
syn match prog8BuiltInFunc "\<cx16\.entropy_get\>"
syn match prog8BuiltInFunc "\<cx16\.monitor\>"
syn match prog8BuiltInFunc "\<cx16\.rombank\>"
syn match prog8BuiltInFunc "\<cx16\.rambank\>"
syn match prog8BuiltInFunc "\<cx16\.vpeek\>"
syn match prog8BuiltInFunc "\<cx16\.vaddr\>"
syn match prog8BuiltInFunc "\<cx16\.vpoke\>"
syn match prog8BuiltInFunc "\<cx16\.vpoke_or\>"
syn match prog8BuiltInFunc "\<cx16\.vpoke_and\>"
syn match prog8BuiltInFunc "\<cx16\.vpoke_xor\>"
syn match prog8BuiltInFunc "\<cx16\.vload\>"
syn match prog8BuiltInFunc "\<cx16\.FB_set_pixels_from_buf\>"
syn match prog8BuiltInFunc "\<cx16\.init_system\>"
syn match prog8BuiltInFunc "\<cx16\.init_system_phase2\>"
syn match prog8BuiltInFunc "\<cx16\.set_irq\>"
syn match prog8BuiltInFunc "\<cx16\.restore_irq\>"
syn match prog8BuiltInFunc "\<cx16\.set_rasterirq\>"
syn match prog8BuiltInFunc "\<cx16\.set_rasterline\>"
syn match prog8BuiltInFunc "\<sys\.reset_system\>"
syn match prog8BuiltInFunc "\<sys\.wait\>"
syn match prog8BuiltInFunc "\<sys\.memcopy\>"
syn match prog8BuiltInFunc "\<sys\.memset\>"
syn match prog8BuiltInFunc "\<sys\.memsetw\>"
syn match prog8BuiltInFunc "\<sys\.rsave\>"
syn match prog8BuiltInFunc "\<sys\.rrestore\>"
syn match prog8BuiltInFunc "\<sys\.read_flags\>"
syn match prog8BuiltInFunc "\<sys\.clear_carry\>"
syn match prog8BuiltInFunc "\<sys\.set_carry\>"
syn match prog8BuiltInFunc "\<sys\.clear_irqd\>"
syn match prog8BuiltInFunc "\<sys\.set_irqd\>"
syn match prog8BuiltInFunc "\<sys\.exit\>"
syn match prog8BuiltInFunc "\<sys\.progend\>"
" cx16/textio.p8
syn match prog8BuiltInVar "\<txt\.DEFAULT_WIDTH\>"
syn match prog8BuiltInVar "\<txt\.DEFAULT_HEIGHT\>"
syn match prog8BuiltInFunc "\<txt\.clear_screen\>"
syn match prog8BuiltInFunc "\<txt\.home\>"
syn match prog8BuiltInFunc "\<txt\.nl\>"
syn match prog8BuiltInFunc "\<txt\.spc\>"
syn match prog8BuiltInFunc "\<txt\.column\>"
syn match prog8BuiltInFunc "\<txt\.fill_screen\>"
syn match prog8BuiltInFunc "\<txt\.clear_screenchars\>"
syn match prog8BuiltInFunc "\<txt\.clear_screencolors\>"
syn match prog8BuiltInVar "\<txt\.color_to_charcode\>"
syn match prog8BuiltInFunc "\<txt\.color\>"
syn match prog8BuiltInFunc "\<txt\.color2\>"
syn match prog8BuiltInFunc "\<txt\.lowercase\>"
syn match prog8BuiltInFunc "\<txt\.uppercase\>"
syn match prog8BuiltInFunc "\<txt\.scroll_left\>"
syn match prog8BuiltInFunc "\<txt\.scroll_right\>"
syn match prog8BuiltInFunc "\<txt\.scroll_up\>"
syn match prog8BuiltInFunc "\<txt\.scroll_down\>"
syn match prog8BuiltInFunc "\<txt\.chrout\>"
syn match prog8BuiltInFunc "\<txt\.print\>"
syn match prog8BuiltInFunc "\<txt\.print_ub0\>"
syn match prog8BuiltInFunc "\<txt\.print_ub\>"
syn match prog8BuiltInFunc "\<txt\.print_b\>"
syn match prog8BuiltInFunc "\<txt\.print_ubhex\>"
syn match prog8BuiltInFunc "\<txt\.print_ubbin\>"
syn match prog8BuiltInFunc "\<txt\.print_uwbin\>"
syn match prog8BuiltInFunc "\<txt\.print_uwhex\>"
syn match prog8BuiltInFunc "\<txt\.print_uw0\>"
syn match prog8BuiltInFunc "\<txt\.print_uw\>"
syn match prog8BuiltInFunc "\<txt\.print_w\>"
syn match prog8BuiltInFunc "\<txt\.input_chars\>"
syn match prog8BuiltInFunc "\<txt\.setchr\>"
syn match prog8BuiltInFunc "\<txt\.getchr\>"
syn match prog8BuiltInFunc "\<txt\.setclr\>"
syn match prog8BuiltInFunc "\<txt\.getclr\>"
syn match prog8BuiltInFunc "\<txt\.setcc\>"
syn match prog8BuiltInFunc "\<txt\.setcc2\>"
syn match prog8BuiltInFunc "\<txt\.plot\>"
syn match prog8BuiltInFunc "\<txt\.width\>"
syn match prog8BuiltInFunc "\<txt\.height\>"
" conv.p8
syn match prog8BuiltInFunc "\<conv\.str_ub0\>"
syn match prog8BuiltInFunc "\<conv\.str_ub\>"
syn match prog8BuiltInFunc "\<conv\.str_b\>"
syn match prog8BuiltInFunc "\<conv\.str_ubhex\>"
syn match prog8BuiltInFunc "\<conv\.str_ubbin\>"
syn match prog8BuiltInFunc "\<conv\.str_uwbin\>"
syn match prog8BuiltInFunc "\<conv\.str_uwhex\>"
syn match prog8BuiltInFunc "\<conv\.str_uw\>"
syn match prog8BuiltInFunc "\<conv\.str_w\>"
syn match prog8BuiltInFunc "\<conv\.any2uword\>"
syn match prog8BuiltInFunc "\<conv\.str2ubyte\>"
syn match prog8BuiltInFunc "\<conv\.str2byte\>"
syn match prog8BuiltInFunc "\<conv\.str2uword\>"
syn match prog8BuiltInFunc "\<conv\.str2word\>"
syn match prog8BuiltInFunc "\<conv\.hex2uword\>"
syn match prog8BuiltInFunc "\<conv\.bin2uword\>"
syn match prog8BuiltInFunc "\<conv\.ubyte2decimal\>"
syn match prog8BuiltInFunc "\<conv\.uword2decimal\>"
syn match prog8BuiltInFunc "\<conv\.byte2decimal\>"
syn match prog8BuiltInFunc "\<conv\.ubyte2hex\>"
syn match prog8BuiltInFunc "\<conv\.uword2hex\>"
" cx16logo.p8
syn match prog8BuiltInFunc "\<cx16logo\.logo_at\>"
syn match prog8BuiltInFunc "\<cx16logo\.logo\>"
syn match prog8BuiltInVar "\<cx16logo\.logo_lines\>"
" diskio.p8
syn match prog8BuiltInFunc "\<diskio\.directory\>"
syn match prog8BuiltInFunc "\<diskio\.list_files\>"
syn match prog8BuiltInFunc "\<diskio\.lf_start_list\>"
syn match prog8BuiltInFunc "\<diskio\.lf_next_entry\>"
syn match prog8BuiltInFunc "\<diskio\.lf_end_list\>"
syn match prog8BuiltInFunc "\<diskio\.f_open\>"
syn match prog8BuiltInFunc "\<diskio\.f_read\>"
syn match prog8BuiltInFunc "\<diskio\.f_read_all\>"
syn match prog8BuiltInFunc "\<diskio\.f_readline\>"
syn match prog8BuiltInFunc "\<diskio\.f_close\>"
syn match prog8BuiltInFunc "\<diskio\.status\>"
syn match prog8BuiltInFunc "\<diskio\.save\>"
syn match prog8BuiltInFunc "\<diskio\.load\>"
syn match prog8BuiltInFunc "\<diskio\.delete\>"
syn match prog8BuiltInFunc "\<diskio\.rename\>"
" prog8_lib.p8
syn match prog8BuiltInFunc "\<prog8_lib\.pattern_match\>"
" string.p8
syn match prog8BuiltInFunc "\<string\.length\>"
syn match prog8BuiltInFunc "\<string\.left\>"
syn match prog8BuiltInFunc "\<string\.right\>"
syn match prog8BuiltInFunc "\<string\.slice\>"
syn match prog8BuiltInFunc "\<string\.find\>"
syn match prog8BuiltInFunc "\<string\.copy\>"
syn match prog8BuiltInFunc "\<string\.compare\>"
syn match prog8BuiltInFunc "\<string\.lower\>"
syn match prog8BuiltInFunc "\<string\.upper\>"
" test_stack.p8
syn match prog8BuiltInFunc "\<test_stack\.test\>"
hi def link prog8BuiltInVar Identifier
hi def link prog8BuiltInFunc Function

View File

@ -1 +1,22 @@
TODO
Vim syntax highlighting definitions.
Created by Elektron72 on github
To install:
Copy prog8.vim and prog8_builtins.vim into ~/.vim/syntax/. If you will never
use highlighting for built-in functions and variables, you do not need to
copy prog8_builtins.vim.
To enable:
Type:
:set ft=prog8
to enable syntax highlighting in the open file. Alternatively, if you would
like to enable syntax highlighting for all .p8 files, add the following line
to your .vimrc:
au BufRead,BufNewFile *.p8 setfiletype prog8
If you would like to disable highlighting for built-in functions and
variables without deleting or renaming the file, add the following line to
your .vimrc:
let g:prog8_no_highlight_builtins = 1
(The value doesn't actually matter, only that the variable is defined.)