diff --git a/compiler/res/prog8lib/string.p8 b/compiler/res/prog8lib/string.p8 index ff4054fd0..1d21bf9b6 100644 --- a/compiler/res/prog8lib/string.p8 +++ b/compiler/res/prog8lib/string.p8 @@ -129,7 +129,7 @@ _startloop dey asmsub find(uword string @R0, ubyte character @A) -> ubyte @A, ubyte @Pc { ; Locates the first position of the given character in the string, - ; returns Carry set if found + index in A, or Carry clear if not found. + ; returns Carry set if found + index in A, or A=0 + Carry clear if not found. %asm {{ ; need to copy the the cx16 virtual registers to zeropage to make this run on C64... sta P8ZP_SCRATCH_B1 @@ -144,7 +144,8 @@ _startloop dey beq _found iny bne - -_notfound clc +_notfound lda #0 + clc rts _found tya sec diff --git a/compiler/src/prog8/CompilerMain.kt b/compiler/src/prog8/CompilerMain.kt index e5ce4c711..4aa07c3cd 100644 --- a/compiler/src/prog8/CompilerMain.kt +++ b/compiler/src/prog8/CompilerMain.kt @@ -10,10 +10,7 @@ import prog8.compiler.CompilationResult import prog8.compiler.CompilerArguments import prog8.compiler.compileProgram import java.io.File -import java.nio.file.FileSystems -import java.nio.file.Path -import java.nio.file.Paths -import java.nio.file.StandardWatchEventKinds +import java.nio.file.* import java.time.LocalDateTime import kotlin.system.exitProcess @@ -148,16 +145,26 @@ private fun compileMain(args: Array): Boolean { } println("[${LocalDateTime.now().withNano(0)}] Waiting for file changes.") + fun determineRecompilationNeeded(event: WatchKey): Boolean { + if(event.isValid) { + for (changed in event.pollEvents()) { + if (changed.kind() == StandardWatchEventKinds.ENTRY_MODIFY) { + val changedPath = changed.context() as Path + if (allImportedFiles.any { it.fileName == changedPath.fileName }) { + println(" change detected: $changedPath") + return true + } + } + } + } + return false + } + var recompile=false while(!recompile) { val event = watchservice.take() - for (changed in event.pollEvents()) { - val changedPath = changed.context() as Path - if(allImportedFiles.any { it.fileName == changedPath.fileName }) { - println(" change detected: $changedPath") - recompile = true - } - } + Thread.sleep(50) // avoid multiple events on same file + recompile = determineRecompilationNeeded(event) event.reset() } diff --git a/compiler/test/TestCompilerOnExamples.kt b/compiler/test/TestCompilerOnExamples.kt index a484ad48f..39ba9c4d6 100644 --- a/compiler/test/TestCompilerOnExamples.kt +++ b/compiler/test/TestCompilerOnExamples.kt @@ -127,6 +127,7 @@ class TestCompilerOnExamplesBothC64andCx16: FunSpec({ listOf( "animals", "balls", + "bsieve", "cube3d", "cube3d-float", "cube3d-gfx", diff --git a/docs/source/libraries.rst b/docs/source/libraries.rst index 2cacd156e..b30232eda 100644 --- a/docs/source/libraries.rst +++ b/docs/source/libraries.rst @@ -172,7 +172,7 @@ Provides string manipulation routines. ``find(string, char) -> ubyte index + carry bit`` Locates the first position of the given character in the string, returns carry bit set if found - and the index in the string. Or carry bit clear if the character was not found. + and the index in the string. Or 0+carry bit clear if the character was not found. ``compare(string1, string2) -> ubyte result`` Returns -1, 0 or 1 depeding on wether string1 sorts before, equal or after string2. diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 3d2c81fe2..1304b194f 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,6 +3,8 @@ TODO For next release ^^^^^^^^^^^^^^^^ +- can we optimize logical expresions such as if input_size and command_line[0]!=159 to not use stack eval anymore? + ... diff --git a/examples/bsieve.p8 b/examples/bsieve.p8 new file mode 100644 index 000000000..14665c5d3 --- /dev/null +++ b/examples/bsieve.p8 @@ -0,0 +1,51 @@ +%import textio +%import floats +%zeropage basicsafe +%option no_sysinit + +; The "Byte Sieve" test. https://en.wikipedia.org/wiki/Byte_Sieve +; Note: this program is compatible with C64 and CX16. + +main { + sub start() { + + c64.SETTIM(0, 0, 0) + + const ubyte ITERS = 10 + uword count + uword i + uword prime + uword k + const uword SIZEPL = 8191 + uword flags_ptr = memory("flags", SIZEPL, $100) + + txt.print("calculating...\n") + + repeat ITERS { + sys.memset(flags_ptr, SIZEPL, 1) + count = 0 + for i in 0 to SIZEPL-1 { + if @(flags_ptr+i) { + prime = i + i + 3 + k = i + prime + while k <= SIZEPL-1 { + @(flags_ptr + k) = false + k += prime + } +; txt.print_uw(prime) +; txt.spc() + count++ + } + } + } + + txt.print_uw(count) + txt.print(" primes\n") + + float time = c64.RDTIM16() / 60.0 + floats.print_f(time) + txt.print(" sec total = ") + floats.print_f(time/ITERS) + txt.print(" sec per iteration\n") + } +}