diff --git a/compiler/res/prog8lib/string.p8 b/compiler/res/prog8lib/string.p8 index 59f49850b..826ad5fa7 100644 --- a/compiler/res/prog8lib/string.p8 +++ b/compiler/res/prog8lib/string.p8 @@ -361,4 +361,26 @@ fail clc ; yes, no match found, return with c=0 rts }} } + + + asmsub hash(str string @R0) -> ubyte @A { + ; experimental 8 bit hashing function. + ; hash(-1)=179; hash(i) = ROL hash(i-1) XOR string[i] + ; (experimental because the quality of the resulting hash value still has to be determined) + %asm {{ + lda #179 + sta P8ZP_SCRATCH_REG + ldy #0 + clc +- lda (cx16.r0),y + beq + + rol P8ZP_SCRATCH_REG + eor P8ZP_SCRATCH_REG + sta P8ZP_SCRATCH_REG + iny + bne - ++ lda P8ZP_SCRATCH_REG + rts + }} + } } diff --git a/compiler/res/prog8lib/virtual/string.p8 b/compiler/res/prog8lib/virtual/string.p8 index 0d1810b52..a57e722c7 100644 --- a/compiler/res/prog8lib/virtual/string.p8 +++ b/compiler/res/prog8lib/virtual/string.p8 @@ -157,4 +157,20 @@ string { return false return compare(st + str_len - suffix_len, suffix) == 0 } + + sub hash(str st) -> ubyte { + ; experimental 8 bit hashing function. + ; hash(-1)=179; hash(i) = ROL hash(i-1) XOR string[i] + ; (experimental because the quality of the resulting hash value still has to be determined) + ubyte hashcode = 179 + ubyte ix + repeat { + if st[ix] { + rol(hashcode) + hashcode ^= st[ix] + ix++ + } else + return hashcode + } + } } diff --git a/docs/source/libraries.rst b/docs/source/libraries.rst index f4ec3efed..4653cf645 100644 --- a/docs/source/libraries.rst +++ b/docs/source/libraries.rst @@ -276,6 +276,10 @@ Provides string manipulation routines. Returns 1 (true) if the string matches the pattern, 0 (false) if not. '?' in the pattern matches any one character. '*' in the pattern matches any substring. +``hash (string) -> ubyte`` + Returns a simple 8 bit hash value for the given string. + *Experimental.* The quality of the resulting hash value still has to be determined. + floats ------ diff --git a/docs/source/todo.rst b/docs/source/todo.rst index b79ffce3f..ae4eb5225 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -2,6 +2,15 @@ TODO ==== +- fix wrong result of: + ubyte b = 4 + float c + %asm {{ + nop + }} + c += b*b + which works if c is a uword instead... + - [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 .... ... diff --git a/examples/test.p8 b/examples/test.p8 index a300eb315..dbba2d187 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,130 +1,19 @@ %import textio +%import string %zeropage basicsafe -; $3d5 - main { - ubyte counter - uword wcounter - ubyte end - uword wend - sub start() { - end=10 - for cx16.r2L in 0 to end-1 { - txt.print_ub(cx16.r2L) + str[] names = [iso:"irmen", iso:"jurrian", iso:"houtzaagmolen 41", iso:"the Quick Brown Fox jumps Over the LAZY dog!"] + + ; txt.iso() + + uword name + for name in names { + txt.print_ub(string.hash(name)) txt.spc() + txt.print(name) + txt.nl() } - txt.nl() - - cx16.r2L=0 - labeltje: - txt.print_ub(cx16.r2L) - txt.spc() - cx16.r2L++ - if cx16.r2L!=end - goto labeltje - txt.nl() - - cx16.r0=0 - forloops() - txt.print_uw(cx16.r0) - txt.nl() - - cx16.r0=0 - untilloops() - txt.print_uw(cx16.r0) - txt.nl() - } - - sub forloops() { - end=10 - for counter in 0 to end { - cx16.r0++ - } - for counter in 0 to end-1 { - cx16.r0++ - } - end=0 - for counter in 0 to end { - cx16.r0++ - } - for counter in 0 to end-1 { - cx16.r0++ - } - end=255 - for counter in 0 to end { - cx16.r0++ - } - for counter in 0 to end-1 { - cx16.r0++ - } - - wend=1000 - for wcounter in 0 to wend { - cx16.r0++ - } - for wcounter in 0 to wend-1 { - cx16.r0++ - } - } - - sub untilloops() { - - end=10 - counter = 0 - repeat { - cx16.r0++ - if counter==end - break - counter++ - } - counter = 0 - do { - cx16.r0++ - counter++ - } until counter==end - - end=0 - counter = 0 - repeat { - cx16.r0++ - if counter==end - break - counter++ - } - counter = 0 - do { - cx16.r0++ - counter++ - } until counter==end - - counter = 0 - end=255 - repeat { - cx16.r0++ - if counter==end - break - counter++ - } - counter = 0 - do { - cx16.r0++ - counter++ - } until counter==end - - wcounter = 0 - wend=1000 - repeat { - cx16.r0++ - if wcounter==wend - break - wcounter++ - } - wcounter = 0 - do { - cx16.r0++ - wcounter++ - } until wcounter==wend } }