From 00f21e67d543bf6eeda5943a8891caeeb0a991d2 Mon Sep 17 00:00:00 2001 From: Zeex Date: Thu, 9 May 2013 01:32:31 +0700 Subject: [PATCH] Pawn 3.2.3664 code with samp_compatible patches applied --- EXAMPLES/argument.p | 10 + EXAMPLES/c2f.p | 14 + EXAMPLES/capt.p | 37 + EXAMPLES/cards.p | 65 + EXAMPLES/chat.p | 31 + EXAMPLES/comment.p | 45 + EXAMPLES/faculty.p | 20 + EXAMPLES/fib.p | 26 + EXAMPLES/gcd.p | 17 + EXAMPLES/gtkcalc.p | 297 ++ EXAMPLES/hanoi.p | 17 + EXAMPLES/hello.p | 2 + EXAMPLES/hello2.p | 6 + EXAMPLES/julian.p | 61 + EXAMPLES/ones.p | 62 + EXAMPLES/queue.p | 78 + EXAMPLES/quine.p | 1 + EXAMPLES/randlist.p | 39 + EXAMPLES/readfile.p | 25 + EXAMPLES/rot13.p | 21 + EXAMPLES/rpn.p | 12 + EXAMPLES/rpnparse.inc | 71 + EXAMPLES/set.p | 46 + EXAMPLES/sieve.p | 16 + EXAMPLES/stack.inc | 26 + EXAMPLES/strtok.inc | 25 + EXAMPLES/traffic.p | 35 + EXAMPLES/traffic2.p | 83 + EXAMPLES/turtle.p | 26 + EXAMPLES/wcount.p | 46 + EXAMPLES/weekday.p | 164 + INCLUDE/amxdll.inc | 78 + INCLUDE/args.inc | 15 + INCLUDE/console.inc | 37 + INCLUDE/core.inc | 34 + INCLUDE/datagram.inc | 18 + INCLUDE/default.inc | 2 + INCLUDE/file.inc | 44 + INCLUDE/fixed.inc | 95 + INCLUDE/float.inc | 184 + INCLUDE/process.inc | 19 + INCLUDE/rational.inc | 53 + INCLUDE/string.inc | 35 + INCLUDE/time.inc | 22 + SOURCE/amx/CMakeLists.txt | 206 + SOURCE/amx/amx.c | 4634 ++++++++++++++++++++ SOURCE/amx/amx.h | 468 ++ SOURCE/amx/amxDGram.def | 6 + SOURCE/amx/amxDGram.rc | 54 + SOURCE/amx/amxFile.rc | 54 + SOURCE/amx/amxFixed.def | 6 + SOURCE/amx/amxFixed.rc | 54 + SOURCE/amx/amxFloat.def | 6 + SOURCE/amx/amxFloat.rc | 54 + SOURCE/amx/amxProcess.def | 6 + SOURCE/amx/amxProcess.rc | 54 + SOURCE/amx/amxargs.c | 401 ++ SOURCE/amx/amxargs.rc | 54 + SOURCE/amx/amxaux.c | 167 + SOURCE/amx/amxaux.h | 54 + SOURCE/amx/amxcons.c | 1266 ++++++ SOURCE/amx/amxcons.h | 17 + SOURCE/amx/amxcore.c | 514 +++ SOURCE/amx/amxdbg.c | 474 ++ SOURCE/amx/amxdbg.h | 172 + SOURCE/amx/amxdef.asm | 86 + SOURCE/amx/amxdefn.asm | 86 + SOURCE/amx/amxdgram.c | 356 ++ SOURCE/amx/amxexec.asm | 2112 +++++++++ SOURCE/amx/amxexecn.asm | 2021 +++++++++ SOURCE/amx/amxfile.c | 796 ++++ SOURCE/amx/amxfile.def | 6 + SOURCE/amx/amxgc.c | 307 ++ SOURCE/amx/amxgc.h | 54 + SOURCE/amx/amxjitr.asm | 2229 ++++++++++ SOURCE/amx/amxjits.asm | 2261 ++++++++++ SOURCE/amx/amxjitsn.asm | 2404 +++++++++++ SOURCE/amx/amxprocess.c | 932 ++++ SOURCE/amx/amxstring.c | 883 ++++ SOURCE/amx/amxstring.def | 6 + SOURCE/amx/amxstring.rc | 54 + SOURCE/amx/amxtime.c | 350 ++ SOURCE/amx/amxtime.def | 6 + SOURCE/amx/amxtime.rc | 54 + SOURCE/amx/dllmain.c | 79 + SOURCE/amx/examples/logfile.cpp | 71 + SOURCE/amx/examples/power.c | 46 + SOURCE/amx/fixed.c | 744 ++++ SOURCE/amx/float.c | 362 ++ SOURCE/amx/fpattern.c | 906 ++++ SOURCE/amx/fpattern.h | 187 + SOURCE/amx/obj/amxexecc.obj | Bin 0 -> 10356 bytes SOURCE/amx/obj/amxexecs.obj | Bin 0 -> 10340 bytes SOURCE/amx/obj/amxjitr.obj | Bin 0 -> 10505 bytes SOURCE/amx/obj/amxjits.obj | Bin 0 -> 10543 bytes SOURCE/amx/osdefs.h | 98 + SOURCE/amx/pawndbg.c | 2865 +++++++++++++ SOURCE/amx/pawnrun.c | 397 ++ SOURCE/amx/pawnrun/prun1.c | 56 + SOURCE/amx/pawnrun/prun2.c | 82 + SOURCE/amx/pawnrun/prun3.c | 190 + SOURCE/amx/pawnrun/prun4.c | 112 + SOURCE/amx/pawnrun/prun5.c | 359 ++ SOURCE/amx/pawnrun/prun_jit.c | 267 ++ SOURCE/amx/pawnrun/readme.txt | 72 + SOURCE/amx/term_ga.c | 517 +++ SOURCE/amx/term_ga.h | 76 + SOURCE/amx/termwin.c | 1073 +++++ SOURCE/amx/termwin.h | 80 + SOURCE/bin/pawn.ico | Bin 0 -> 8478 bytes SOURCE/compiler/CMakeLists.txt | 72 + SOURCE/compiler/libpawnc.c | 322 ++ SOURCE/compiler/libpawnc.def | 8 + SOURCE/compiler/libpawnc.def.borland | 8 + SOURCE/compiler/libpawnc.lbc | 6 + SOURCE/compiler/libpawnc.rc | 63 + SOURCE/compiler/lstring.c | 124 + SOURCE/compiler/lstring.h | 18 + SOURCE/compiler/memfile.c | 109 + SOURCE/compiler/memfile.h | 33 + SOURCE/compiler/pawncc.c | 30 + SOURCE/compiler/pawncc.def | 2 + SOURCE/compiler/pawncc.def.borland | 5 + SOURCE/compiler/sc.h | 825 ++++ SOURCE/compiler/sc1.c | 5940 ++++++++++++++++++++++++++ SOURCE/compiler/sc2.c | 2949 +++++++++++++ SOURCE/compiler/sc3.c | 2519 +++++++++++ SOURCE/compiler/sc4.c | 1335 ++++++ SOURCE/compiler/sc5.c | 228 + SOURCE/compiler/sc5.scp | 342 ++ SOURCE/compiler/sc6.c | 1299 ++++++ SOURCE/compiler/sc7.c | 703 +++ SOURCE/compiler/sc7.scp | 2023 +++++++++ SOURCE/compiler/scexpand.c | 68 + SOURCE/compiler/sci18n.c | 428 ++ SOURCE/compiler/sclist.c | 534 +++ SOURCE/compiler/scmemfil.c | 165 + SOURCE/compiler/scpack.c | 450 ++ SOURCE/compiler/scstate.c | 375 ++ SOURCE/compiler/scstub.c | 29 + SOURCE/compiler/scvars.c | 113 + SOURCE/compiler/svnrev.h | 16 + SOURCE/linux/binreloc.c | 766 ++++ SOURCE/linux/binreloc.h | 80 + SOURCE/linux/getch.c | 101 + SOURCE/linux/getch.h | 15 + SOURCE/linux/sclinux.h | 47 + XML/pawndoc.css | 256 ++ XML/pawndoc.xsl | 286 ++ history.txt | 2112 +++++++++ license.txt | 35 + readme.txt | 297 ++ 152 files changed, 59559 insertions(+) create mode 100644 EXAMPLES/argument.p create mode 100644 EXAMPLES/c2f.p create mode 100644 EXAMPLES/capt.p create mode 100644 EXAMPLES/cards.p create mode 100644 EXAMPLES/chat.p create mode 100644 EXAMPLES/comment.p create mode 100644 EXAMPLES/faculty.p create mode 100644 EXAMPLES/fib.p create mode 100644 EXAMPLES/gcd.p create mode 100644 EXAMPLES/gtkcalc.p create mode 100644 EXAMPLES/hanoi.p create mode 100644 EXAMPLES/hello.p create mode 100644 EXAMPLES/hello2.p create mode 100644 EXAMPLES/julian.p create mode 100644 EXAMPLES/ones.p create mode 100644 EXAMPLES/queue.p create mode 100644 EXAMPLES/quine.p create mode 100644 EXAMPLES/randlist.p create mode 100644 EXAMPLES/readfile.p create mode 100644 EXAMPLES/rot13.p create mode 100644 EXAMPLES/rpn.p create mode 100644 EXAMPLES/rpnparse.inc create mode 100644 EXAMPLES/set.p create mode 100644 EXAMPLES/sieve.p create mode 100644 EXAMPLES/stack.inc create mode 100644 EXAMPLES/strtok.inc create mode 100644 EXAMPLES/traffic.p create mode 100644 EXAMPLES/traffic2.p create mode 100644 EXAMPLES/turtle.p create mode 100644 EXAMPLES/wcount.p create mode 100644 EXAMPLES/weekday.p create mode 100644 INCLUDE/amxdll.inc create mode 100644 INCLUDE/args.inc create mode 100644 INCLUDE/console.inc create mode 100644 INCLUDE/core.inc create mode 100644 INCLUDE/datagram.inc create mode 100644 INCLUDE/default.inc create mode 100644 INCLUDE/file.inc create mode 100644 INCLUDE/fixed.inc create mode 100644 INCLUDE/float.inc create mode 100644 INCLUDE/process.inc create mode 100644 INCLUDE/rational.inc create mode 100644 INCLUDE/string.inc create mode 100644 INCLUDE/time.inc create mode 100644 SOURCE/amx/CMakeLists.txt create mode 100644 SOURCE/amx/amx.c create mode 100644 SOURCE/amx/amx.h create mode 100644 SOURCE/amx/amxDGram.def create mode 100644 SOURCE/amx/amxDGram.rc create mode 100644 SOURCE/amx/amxFile.rc create mode 100644 SOURCE/amx/amxFixed.def create mode 100644 SOURCE/amx/amxFixed.rc create mode 100644 SOURCE/amx/amxFloat.def create mode 100644 SOURCE/amx/amxFloat.rc create mode 100644 SOURCE/amx/amxProcess.def create mode 100644 SOURCE/amx/amxProcess.rc create mode 100644 SOURCE/amx/amxargs.c create mode 100644 SOURCE/amx/amxargs.rc create mode 100644 SOURCE/amx/amxaux.c create mode 100644 SOURCE/amx/amxaux.h create mode 100644 SOURCE/amx/amxcons.c create mode 100644 SOURCE/amx/amxcons.h create mode 100644 SOURCE/amx/amxcore.c create mode 100644 SOURCE/amx/amxdbg.c create mode 100644 SOURCE/amx/amxdbg.h create mode 100644 SOURCE/amx/amxdef.asm create mode 100644 SOURCE/amx/amxdefn.asm create mode 100644 SOURCE/amx/amxdgram.c create mode 100644 SOURCE/amx/amxexec.asm create mode 100644 SOURCE/amx/amxexecn.asm create mode 100644 SOURCE/amx/amxfile.c create mode 100644 SOURCE/amx/amxfile.def create mode 100644 SOURCE/amx/amxgc.c create mode 100644 SOURCE/amx/amxgc.h create mode 100644 SOURCE/amx/amxjitr.asm create mode 100644 SOURCE/amx/amxjits.asm create mode 100644 SOURCE/amx/amxjitsn.asm create mode 100644 SOURCE/amx/amxprocess.c create mode 100644 SOURCE/amx/amxstring.c create mode 100644 SOURCE/amx/amxstring.def create mode 100644 SOURCE/amx/amxstring.rc create mode 100644 SOURCE/amx/amxtime.c create mode 100644 SOURCE/amx/amxtime.def create mode 100644 SOURCE/amx/amxtime.rc create mode 100644 SOURCE/amx/dllmain.c create mode 100644 SOURCE/amx/examples/logfile.cpp create mode 100644 SOURCE/amx/examples/power.c create mode 100644 SOURCE/amx/fixed.c create mode 100644 SOURCE/amx/float.c create mode 100644 SOURCE/amx/fpattern.c create mode 100644 SOURCE/amx/fpattern.h create mode 100644 SOURCE/amx/obj/amxexecc.obj create mode 100644 SOURCE/amx/obj/amxexecs.obj create mode 100644 SOURCE/amx/obj/amxjitr.obj create mode 100644 SOURCE/amx/obj/amxjits.obj create mode 100644 SOURCE/amx/osdefs.h create mode 100644 SOURCE/amx/pawndbg.c create mode 100644 SOURCE/amx/pawnrun.c create mode 100644 SOURCE/amx/pawnrun/prun1.c create mode 100644 SOURCE/amx/pawnrun/prun2.c create mode 100644 SOURCE/amx/pawnrun/prun3.c create mode 100644 SOURCE/amx/pawnrun/prun4.c create mode 100644 SOURCE/amx/pawnrun/prun5.c create mode 100644 SOURCE/amx/pawnrun/prun_jit.c create mode 100644 SOURCE/amx/pawnrun/readme.txt create mode 100644 SOURCE/amx/term_ga.c create mode 100644 SOURCE/amx/term_ga.h create mode 100644 SOURCE/amx/termwin.c create mode 100644 SOURCE/amx/termwin.h create mode 100644 SOURCE/bin/pawn.ico create mode 100644 SOURCE/compiler/CMakeLists.txt create mode 100644 SOURCE/compiler/libpawnc.c create mode 100644 SOURCE/compiler/libpawnc.def create mode 100644 SOURCE/compiler/libpawnc.def.borland create mode 100644 SOURCE/compiler/libpawnc.lbc create mode 100644 SOURCE/compiler/libpawnc.rc create mode 100644 SOURCE/compiler/lstring.c create mode 100644 SOURCE/compiler/lstring.h create mode 100644 SOURCE/compiler/memfile.c create mode 100644 SOURCE/compiler/memfile.h create mode 100644 SOURCE/compiler/pawncc.c create mode 100644 SOURCE/compiler/pawncc.def create mode 100644 SOURCE/compiler/pawncc.def.borland create mode 100644 SOURCE/compiler/sc.h create mode 100644 SOURCE/compiler/sc1.c create mode 100644 SOURCE/compiler/sc2.c create mode 100644 SOURCE/compiler/sc3.c create mode 100644 SOURCE/compiler/sc4.c create mode 100644 SOURCE/compiler/sc5.c create mode 100644 SOURCE/compiler/sc5.scp create mode 100644 SOURCE/compiler/sc6.c create mode 100644 SOURCE/compiler/sc7.c create mode 100644 SOURCE/compiler/sc7.scp create mode 100644 SOURCE/compiler/scexpand.c create mode 100644 SOURCE/compiler/sci18n.c create mode 100644 SOURCE/compiler/sclist.c create mode 100644 SOURCE/compiler/scmemfil.c create mode 100644 SOURCE/compiler/scpack.c create mode 100644 SOURCE/compiler/scstate.c create mode 100644 SOURCE/compiler/scstub.c create mode 100644 SOURCE/compiler/scvars.c create mode 100644 SOURCE/compiler/svnrev.h create mode 100644 SOURCE/linux/binreloc.c create mode 100644 SOURCE/linux/binreloc.h create mode 100644 SOURCE/linux/getch.c create mode 100644 SOURCE/linux/getch.h create mode 100644 SOURCE/linux/sclinux.h create mode 100644 XML/pawndoc.css create mode 100644 XML/pawndoc.xsl create mode 100644 history.txt create mode 100644 license.txt create mode 100644 readme.txt diff --git a/EXAMPLES/argument.p b/EXAMPLES/argument.p new file mode 100644 index 0000000..487b213 --- /dev/null +++ b/EXAMPLES/argument.p @@ -0,0 +1,10 @@ +#include + +main() + { + printf "Argument count = %d\n", argcount() + + new opt[100] + for (new index = 0; argindex(index, opt); index++) + printf "Argument %d = %s\n", index, opt + } diff --git a/EXAMPLES/c2f.p b/EXAMPLES/c2f.p new file mode 100644 index 0000000..d7cdb6d --- /dev/null +++ b/EXAMPLES/c2f.p @@ -0,0 +1,14 @@ +#include + +main() + { + new Rational: Celsius + new Rational: Fahrenheit + + print "Celsius\t Fahrenheit\n" + for (Celsius = 5; Celsius <= 25; Celsius++) + { + Fahrenheit = (Celsius * 1.8) + 32 + printf "%r \t %r\n", Celsius, Fahrenheit + } + } diff --git a/EXAMPLES/capt.p b/EXAMPLES/capt.p new file mode 100644 index 0000000..7327310 --- /dev/null +++ b/EXAMPLES/capt.p @@ -0,0 +1,37 @@ +bool: ispacked(string[]) + return bool: (string[0] > charmax) + +my_strlen(string[]) + { + new len = 0 + if (ispacked(string)) + while (string{len} != EOS) /* get character from pack */ + ++len + else + while (string[len] != EOS) /* get cell */ + ++len + return len + } + +strupper(string[]) + { + assert ispacked(string) + + for (new i=0; string{i} != EOS; ++i) + string{i} = toupper(string{i}) + } + +main() + { + new s[10] + + for (new i = 0; i < 5; i++) + s{i}=i+'a' + s{5}=EOS + + printf("String is %s\n", ispacked(s) ? "packed" : "unpacked") + printf("String length is %d\n", my_strlen(s)) + printf("Original: %s\n", s) + strupper(s) + printf("Upper case: %s\n", s) + } diff --git a/EXAMPLES/cards.p b/EXAMPLES/cards.p new file mode 100644 index 0000000..e5cf645 --- /dev/null +++ b/EXAMPLES/cards.p @@ -0,0 +1,65 @@ +enum _: CardSuits + { + Clubs, + Diamonds, + Hearts, + Spades, + } + +const CardTypes = 13 +const TotalCards = CardSuits * CardTypes + +enum CardDescription + { + CardName[10 char], + CardSuit, + CardValue, + } + +new CardNames[CardTypes][] = { !"Ace", !"Two", !"Three", !"Four", !"Five", + !"Six", !"Seven", !"Eight", !"Nine", !"Ten", + !"Jack", !"Queen", !"King" } +new CardValues[CardTypes] = { 11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10 } + +main() + { + new Cards[ TotalCards ][ CardDescription ] + + /* fill in the cards */ + for (new suit = 0; suit < CardSuits; suit++) + { + for (new card = 0; card < CardTypes; card++) + { + new index = suit*CardTypes + card + strpack Cards[ index ][CardName], CardNames[ card ] + Cards[ index ][ CardSuit ] = suit + Cards[ index ][ CardValue ] = CardValues[ card ] + } + } + + /* shuffle the cards (swap an arbitrary number of randomly selected cards) */ + for (new iter = 0; iter < 200; iter++) + { + new first = random(TotalCards) + new second = random(TotalCards) + new TempCard[ CardDescription ] + TempCard = Cards[first] + Cards[ first ] = Cards[ second ] + Cards[ second ] = TempCard + } + + /* print the cards with a subroutine */ + for (new card = 0; card < TotalCards; card++) + PrintCard Cards[ card] + } + +PrintCard( TheCard[ CardDescription ] ) + { + new SuitNames[ CardSuits ][] = { !"Clubs", !"Diamonds", + !"Hearts", !"Spades" } + + printf !"%s of %s (valued %d)\n", + TheCard[ CardName ], + SuitNames[ TheCard[ CardSuit ] ], + TheCard[ CardValue ] + } diff --git a/EXAMPLES/chat.p b/EXAMPLES/chat.p new file mode 100644 index 0000000..0fa4d08 --- /dev/null +++ b/EXAMPLES/chat.p @@ -0,0 +1,31 @@ +#include + +@receivestring(const message[], const source[]) + printf "[%s] says: %s\n", source, message + +@keypressed(key) + { + static string[100 char] + static index + + if (key == '\e') + exit /* quit on 'Esc' key */ + + echo key + if (key == '\r' || key == '\n' || index char == sizeof string) + { + string{index} = '\0' /* terminate string */ + sendstring string + index = 0 + string[index] = '\0' + } + else + string{index++} = key + } + +echo(key) + { + new string[2 char] = { 0 } + string{0} = key == '\r' ? '\n' : key + printf string + } diff --git a/EXAMPLES/comment.p b/EXAMPLES/comment.p new file mode 100644 index 0000000..e1d83fb --- /dev/null +++ b/EXAMPLES/comment.p @@ -0,0 +1,45 @@ +/* parse C comments interactively, using events and a state machine */ + +main() + state plain + +@keypressed(key) + { + state (key == '/') slash + if (key != '/') + echo key + } + +@keypressed(key) + { + state (key != '/') plain + state (key == '*') comment + echo '/' /* print '/' held back from previous state */ + if (key != '/') + echo key + } + +@keypressed(key) + { + echo key + state (key == '*') star + } + +@keypressed(key) + { + echo key + state (key != '*') comment + state (key == '/') plain + } + +echo(key) + printchar key, yellow + +echo(key) + printchar key, green + +printchar(ch, colour) + { + setattr .foreground = colour + printf "%c", ch + } diff --git a/EXAMPLES/faculty.p b/EXAMPLES/faculty.p new file mode 100644 index 0000000..5e20df6 --- /dev/null +++ b/EXAMPLES/faculty.p @@ -0,0 +1,20 @@ +/* Calculation of the faculty of a value */ + +main() + { + print "Enter a value: " + new v = getvalue() + new f = faculty(v) + printf "The faculty of %d is %d\n", v, f + } + +faculty(n) + { + assert n >= 0 + + new result = 1 + while (n > 0) + result *= n-- + + return result + } diff --git a/EXAMPLES/fib.p b/EXAMPLES/fib.p new file mode 100644 index 0000000..87f7945 --- /dev/null +++ b/EXAMPLES/fib.p @@ -0,0 +1,26 @@ +/* Calculation of Fibonacci numbers by iteration */ + +main() + { + print "Enter a value: " + new v = getvalue() + if (v > 0) + printf "The value of Fibonacci number %d is %d\n", + v, fibonacci(v) + else + printf "The Fibonacci number %d does not exist\n", v + } + +fibonacci(n) + { + assert n > 0 + + new a = 0, b = 1 + for (new i = 2; i < n; i++) + { + new c = a + b + a = b + b = c + } + return a + b + } diff --git a/EXAMPLES/gcd.p b/EXAMPLES/gcd.p new file mode 100644 index 0000000..ca21665 --- /dev/null +++ b/EXAMPLES/gcd.p @@ -0,0 +1,17 @@ +/* + The greatest common divisor of two values, + using Euclides' algorithm . +*/ + +main() + { + print "Input two values\n" + new a = getvalue() + new b = getvalue() + while (a != b) + if (a > b) + a = a - b + else + b = b - a + printf "The greatest common divisor is %d\n", a + } diff --git a/EXAMPLES/gtkcalc.p b/EXAMPLES/gtkcalc.p new file mode 100644 index 0000000..353d6d3 --- /dev/null +++ b/EXAMPLES/gtkcalc.p @@ -0,0 +1,297 @@ +/* A demo GTK application in Pawn, using gtk-server and the "process control" + * module for Pawn. This example also illustrates the use of (communicating) + * finite state machines. + */ +#include +#include + +enum Btn + { + Btn0, Btn1, Btn2, + Btn3, Btn4, Btn5, + Btn6, Btn7, Btn8, + Btn9, BtnDot, BtnC, + BtnCE, BtnPlus, BtnMin, + BtnMul, BtnDiv, BtnEqual, + BtnNone, + } + +static entry /* GTK "entry" widget */ +static numberstring[40 char] +static accum +static Btn:pending_op + +adddigit(digit, bool:reset = false) + { + new command[80 char], charstr[2 char] + charstr{0} = (0 <= digit <= 9) ? digit + '0' : digit + if (reset) + numberstring[0] = EOS + strcat numberstring, charstr + strformat command, _, true, "gtk_entry_set_text %d %s", entry, numberstring + GTK(command) + } + +displayresult(value) + { + new command[80 char] + valstr numberstring, value, true + strformat command, _, true, "gtk_entry_set_text %d %s", entry, numberstring + GTK(command) + } + + +resetentry(digit) + { + adddigit '-', .reset = true + adddigit digit + } + +resetentry(digit) <> + { + adddigit digit, .reset = true + } + + +event_0() + { + resetentry 0 + } + +event_0() + { + adddigit 0 + } + +event_1_9(Btn:idx) + { + resetentry _:(idx - Btn0) + state number:int + } + +event_1_9(Btn:idx) + { + adddigit _:(idx - Btn0) + } + +event_dot() + { + resetentry 0 + adddigit '.' + state number:frac + } + +event_dot() + { + adddigit '.' + state number:frac + } + +event_dot() + { + /* reject entry */ + } + +event_minus() + { + state number:negated + resetentry 0 + } + +event_minus() <> + { + event_oper BtnMin /* forward to the "calc" automaton */ + } + + +/* helper function for the calculator automaton */ +performoperation() + { + /* get the other operand, perform the operation */ + new val = strval(numberstring) + switch (pending_op) + { + case BtnPlus: accum += val + case BtnMin: accum -= val + case BtnMul: accum *= val + case BtnDiv: accum = (val == 0) ? 0 : accum / val + } + displayresult accum + } + +event_oper(Btn:idx) + { + /* save operand and operator */ + accum = strval(numberstring) + pending_op = idx + + state number:zero + state calc:pending + } + +event_oper(Btn:idx) + { + performoperation /* do the pending operation */ + pending_op = idx /* save the operator for the next operation */ + state number:zero + } + +event_equal() + { + /* ignore */ + } + +event_equal() + { + performoperation /* do the pending operation */ + state calc:idle /* reset the calculator */ + state number:zero + } + + +event_C() + { + state calc:idle + state number:zero + resetentry 0 + } + +event_CE() + { + state number:zero + resetentry 0 + } + + +main() + { + if (!procexec("gtk-server stdin") && !procexec("gtk-server.exe stdin")) + fatal "unable to launch gtk-server" + + /* make a window */ + GTK("gtk_init NULL NULL") + new win = GTK("gtk_window_new 0") + GTK("gtk_window_set_title %d \"Pawn calculator\"", win) + GTK("gtk_widget_set_usize %d 200 200", win) + + /* add a table (align the other controls) */ + new table = GTK("gtk_table_new 50 50 1") + GTK("gtk_container_add %d %d", win, table) + + /* the number entry */ + entry = GTK("gtk_entry_new") + GTK("gtk_table_attach_defaults %d %d 1 49 1 9", table, entry) + + /* the key pad */ + new buttons[Btn] + buttons[BtnDot] = GTK("gtk_button_new_with_label .") + GTK("gtk_table_attach_defaults %d %d 21 29 41 49", table, buttons[BtnDot]) + buttons[Btn0] = GTK("gtk_button_new_with_label 0") + GTK("gtk_table_attach_defaults %d %d 1 19 41 49", table, buttons[Btn0]) + buttons[Btn1] = GTK("gtk_button_new_with_label 1") + GTK("gtk_table_attach_defaults %d %d 1 9 31 39", table, buttons[Btn1]) + buttons[Btn2] = GTK("gtk_button_new_with_label 2") + GTK("gtk_table_attach_defaults %d %d 11 19 31 39", table, buttons[Btn2]) + buttons[Btn3] = GTK("gtk_button_new_with_label 3") + GTK("gtk_table_attach_defaults %d %d 21 29 31 39", table, buttons[Btn3]) + buttons[Btn4] = GTK("gtk_button_new_with_label 4") + GTK("gtk_table_attach_defaults %d %d 1 9 21 29", table, buttons[Btn4]) + buttons[Btn5] = GTK("gtk_button_new_with_label 5") + GTK("gtk_table_attach_defaults %d %d 11 19 21 29", table, buttons[Btn5]) + buttons[Btn6] = GTK("gtk_button_new_with_label 6") + GTK("gtk_table_attach_defaults %d %d 21 29 21 29", table, buttons[Btn6]) + buttons[Btn7] = GTK("gtk_button_new_with_label 7") + GTK("gtk_table_attach_defaults %d %d 1 9 11 19", table, buttons[Btn7]) + buttons[Btn8] = GTK("gtk_button_new_with_label 8") + GTK("gtk_table_attach_defaults %d %d 11 19 11 19", table, buttons[Btn8]) + buttons[Btn9] = GTK("gtk_button_new_with_label 9") + GTK("gtk_table_attach_defaults %d %d 21 29 11 19", table, buttons[Btn9]) + + buttons[BtnC] = GTK("gtk_button_new_with_label C") + GTK("gtk_table_attach_defaults %d %d 31 39 11 19", table, buttons[BtnC]) + buttons[BtnCE] = GTK("gtk_button_new_with_label CE") + GTK("gtk_table_attach_defaults %d %d 41 49 11 19", table, buttons[BtnCE]) + buttons[BtnPlus] = GTK("gtk_button_new_with_label +") + GTK("gtk_table_attach_defaults %d %d 31 39 21 29", table, buttons[BtnPlus]) + buttons[BtnMin] = GTK("gtk_button_new_with_label -") + GTK("gtk_table_attach_defaults %d %d 41 49 21 29", table, buttons[BtnMin]) + buttons[BtnMul] = GTK("gtk_button_new_with_label x") + GTK("gtk_table_attach_defaults %d %d 31 39 31 39", table, buttons[BtnMul]) + buttons[BtnDiv] = GTK("gtk_button_new_with_label /") + GTK("gtk_table_attach_defaults %d %d 41 49 31 39", table, buttons[BtnDiv]) + buttons[BtnEqual] = GTK("gtk_button_new_with_label =") + GTK("gtk_table_attach_defaults %d %d 31 49 41 49", table, buttons[BtnEqual]) + + /* initialize automata */ + state number:zero + state calc:idle + + /* wait for events, and dispatch them */ + GTK("gtk_widget_show_all %d", win) + + resetentry 0 + new event + new Btn:idx + do + { + event = GTK("gtk_server_callback wait") + + /* find the button matching the event, generate the event */ + for (idx = Btn0; idx < BtnNone && buttons[idx] != event; idx++) + {} + switch (idx) + { + case Btn0: + event_0 + case Btn1 .. Btn9: + event_1_9 idx + case BtnDot: + event_dot + case BtnMin: + event_minus + case BtnPlus, BtnMul, BtnDiv: + event_oper idx + case BtnEqual: + event_equal + case BtnC: + event_C + case BtnCE: + event_CE + } + } + while (event != win); + + /* direct call, because we must not wait for a reply on this command */ + procwrite "gtk_exit 0", true + } + +GTK(const format[], ...) + { + new command[256 char] + switch (numargs()) + { + case 1: + strpack command, format + case 2: + strformat command, _, true, format, getarg(1) + case 3: + strformat command, _, true, format, getarg(1), getarg(2) + case 4: + strformat command, _, true, format, getarg(1), getarg(2), getarg(3) + case 5: + strformat command, _, true, format, getarg(1), getarg(2), getarg(3), getarg(4) + } + procwrite command, true + + new reply[30] + procread reply, .striplf=true + if (strcmp(reply, "ok") == 0) + return true + return strval(reply) + } + +fatal(const message[]) + { + printf "FATAL: %s\n", message + exit + } diff --git a/EXAMPLES/hanoi.p b/EXAMPLES/hanoi.p new file mode 100644 index 0000000..0088c75 --- /dev/null +++ b/EXAMPLES/hanoi.p @@ -0,0 +1,17 @@ +/* The Towers of Hanoi, a game solved through recursion */ + +main() + { + print "How many disks: " + new disks = getvalue() + move 1, 3, 2, disks + } + +move(from, to, spare, numdisks) + { + if (numdisks > 1) + move from, spare, to, numdisks-1 + printf "Move disk from pillar %d to pillar %d\n", from, to + if (numdisks > 1) + move spare, to, from, numdisks-1 + } diff --git a/EXAMPLES/hello.p b/EXAMPLES/hello.p new file mode 100644 index 0000000..64ff621 --- /dev/null +++ b/EXAMPLES/hello.p @@ -0,0 +1,2 @@ +main() + printf "Hello world\n" diff --git a/EXAMPLES/hello2.p b/EXAMPLES/hello2.p new file mode 100644 index 0000000..04974e7 --- /dev/null +++ b/EXAMPLES/hello2.p @@ -0,0 +1,6 @@ +#include + +main() +{ + printf("Hello world\n"); +} \ No newline at end of file diff --git a/EXAMPLES/julian.p b/EXAMPLES/julian.p new file mode 100644 index 0000000..4e7b261 --- /dev/null +++ b/EXAMPLES/julian.p @@ -0,0 +1,61 @@ +/* calculate Julian Day number from a date, and vice versa */ + +main() + { + new d, m, y, jdn + + print "Give a date (dd-mm-yyyy): " + d = getvalue(_, '-', '/') + m = getvalue(_, '-', '/') + y = getvalue() + + jdn = DateToJulian(d, m, y) + printf("Date %d/%d/%d = %d JD\n", d, m, y, jdn) + + print "Give a Julian Day Number: " + jdn = getvalue() + JulianToDate jdn, d, m, y + printf "%d JD = %d/%d/%d\n", jdn, d, m, y + } + +DateToJulian(day, month, year) + { + /* The first year is 1. Year 0 does not exist: it is 1 BC (or -1) */ + assert year != 0 + if (year < 0) + year++ + + /* move January and February to the end of the previous year */ + if (month <= 2) + year--, month += 12 + new jdn = 365*year + year/4 - year/100 + year/400 + + (153*month - 457) / 5 + + day + 1721119 + return jdn + } + +JulianToDate(jdn, &day, &month, &year) + { + jdn -= 1721119 + + /* approximate year, then adjust in a loop */ + year = (400 * jdn) / 146097 + while (365*year + year/4 - year/100 + year/400 < jdn) + year++ + year-- + + /* determine month */ + jdn -= 365*year + year/4 - year/100 + year/400 + month = (5*jdn + 457) / 153 + + /* determine day */ + day = jdn - (153*month - 457) / 5 + + /* move January and February to start of the year */ + if (month > 12) + month -= 12, year++ + + /* adjust negative years (year 0 must become 1 BC, or -1) */ + if (year <= 0) + year-- + } diff --git a/EXAMPLES/ones.p b/EXAMPLES/ones.p new file mode 100644 index 0000000..f784354 --- /dev/null +++ b/EXAMPLES/ones.p @@ -0,0 +1,62 @@ +forward ones: operator+(ones: a, ones: b) +forward ones: operator-(ones: a, ones: b) +forward ones: operator-(ones: a) + +main() + { + new ones: chksum = ones: 0xffffffff + print "Input values in hexadecimal, zero to exit\n" + + new ones: value + do + { + print ">> " + value = ones: getvalue(.base=16) + chksum = chksum + value + printf "Checksum = %x\n", chksum + } + while (value) + } + +stock ones: operator+(ones: a, ones: b) + { + const ones: mask = ones: 0xffff /* word mask */ + const ones: shift = ones: 16 /* word shift */ + + /* add low words and high words separately */ + new ones: r1 = (a & mask) + (b & mask) + new ones: r2 = (a >>> shift) + (b >>> shift) + + new ones: carry + restart: /* code label (goto target) */ + + /* add carry of the new low word to the high word, then + * strip it from the low word + */ + carry = (r1 >>> shift) + r2 += carry + r1 &= mask + + /* add the carry from the new high word back to the low + * word, then strip it from the high word + */ + carry = (r2 >>> shift) + r1 += carry + r2 &= mask + + /* a carry from the high word injected back into the low + * word may cause the new low to overflow, so restart in + * that case + */ + if (carry) + goto restart + + return (r2 << shift) | r1 + } + +stock ones: operator-(ones: a) + return (a == ones: 0xffffffff) ? a : ~a + +stock ones: operator-(ones: a, ones: b) + return a + -b + diff --git a/EXAMPLES/queue.p b/EXAMPLES/queue.p new file mode 100644 index 0000000..d5f44bd --- /dev/null +++ b/EXAMPLES/queue.p @@ -0,0 +1,78 @@ +/* Priority queue (for simple text strings) */ + +enum message + { + text[40 char], + priority + } + +main() + { + new msg[message] + + /* insert a few items (read from console input) */ + printf "Please insert a few messages and their priorities; \ + end with an empty string\n" + for ( ;; ) + { + printf "Message: " + getstring .string = msg[text], .maxlength = 40, .pack = true + if (strlen(msg[text]) == 0) + break + printf "Priority: " + msg[priority] = getvalue() + if (!insert(msg)) + { + printf "Queue is full, cannot insert more items\n" + break + } + } + + /* now print the messages extracted from the queue */ + printf "\nContents of the queue:\n" + while (extract(msg)) + printf "[%d] %s\n", msg[priority], msg[text] + } + +const queuesize = 10 +new queue[queuesize][message] +new queueitems = 0 + +insert(const item[message]) + { + /* check if the queue can hold one more message */ + if (queueitems == queuesize) + return false /* queue is full */ + + /* find the position to insert it to */ + new pos = queueitems /* start at the bottom */ + while (pos > 0 && item[priority] > queue[pos-1][priority]) + --pos /* higher priority: move up a slot */ + + /* make place for the item at the insertion spot */ + for (new i = queueitems; i > pos; --i) + queue[i] = queue[i-1] + + /* add the message to the correct slot */ + queue[pos] = item + queueitems++ + + return true + } + +extract(item[message]) + { + /* check whether the queue has one more message */ + if (queueitems == 0) + return false /* queue is empty */ + + /* copy the topmost item */ + item = queue[0] + --queueitems + + /* move the queue one position up */ + for (new i = 0; i < queueitems; ++i) + queue[i] = queue[i+1] + + return true + } diff --git a/EXAMPLES/quine.p b/EXAMPLES/quine.p new file mode 100644 index 0000000..1be728a --- /dev/null +++ b/EXAMPLES/quine.p @@ -0,0 +1 @@ +new s[]="new s[]=%c%s%c; main() printf s,34,s,34"; main() printf s,34,s,34 diff --git a/EXAMPLES/randlist.p b/EXAMPLES/randlist.p new file mode 100644 index 0000000..4d5d1a1 --- /dev/null +++ b/EXAMPLES/randlist.p @@ -0,0 +1,39 @@ +main() + { + new HandOfCards[10] + FillRandom(HandOfCards, 52) + + print "A draw of 10 numbers from a range of 0 to 51 \ + (inclusive) without duplicates:\n" + for (new i = 0; i < sizeof HandOfCards; i++) + printf "%d ", HandOfCards[i] + } + +FillRandom(Series[], Range, Number = sizeof Series) + { + assert Range >= Number /* cannot select 50 values + * without duplicates in the + * range 0..40, for example */ + new Index = 0 + for (new Seq = Range - Number; Seq < Range; Seq++) + { + new Val = random(Seq + 1) + new Pos = InSeries(Series, Val, Index) + if (Pos >= 0) + { + Series[Index] = Series[Pos] + Series[Pos] = Seq + } + else + Series[Index] = Val + Index++ + } + } + +InSeries(Series[], Value, Top = sizeof Series) + { + for (new i = 0; i < Top; i++) + if (Series[i] == Value) + return i + return -1 + } diff --git a/EXAMPLES/readfile.p b/EXAMPLES/readfile.p new file mode 100644 index 0000000..4f39e7c --- /dev/null +++ b/EXAMPLES/readfile.p @@ -0,0 +1,25 @@ +#include + +main() + { + /* ask for a filename */ + print "Please enter a filename: " + new filename[128 char] + getstring filename, .pack=true + + /* try to open the file */ + new File: file = fopen(filename, io_read) + if (!file) + { + printf "The file '%s' cannot be opened for reading\n", filename + exit + } + + /* dump the file onto the console */ + new line[200] + while (fread(file, line)) + print line, .highlight=true + + /* done */ + fclose file + } diff --git a/EXAMPLES/rot13.p b/EXAMPLES/rot13.p new file mode 100644 index 0000000..3103b0a --- /dev/null +++ b/EXAMPLES/rot13.p @@ -0,0 +1,21 @@ +/* Simple encryption, using ROT13 */ + +main() + { + printf "Please type the string to mangle: " + + new str[100] + getstring str, sizeof str + rot13 str + + printf "After mangling, the string is: \"%s\"\n", str + } + +rot13(string[]) + { + for (new index = 0; string[index]; index++) + if ('a' <= string[index] <= 'z') + string[index] = (string[index] - 'a' + 13) % 26 + 'a' + else if ('A' <= string[index] <= 'Z') + string[index] = (string[index] - 'A' + 13) % 26 + 'A' + } diff --git a/EXAMPLES/rpn.p b/EXAMPLES/rpn.p new file mode 100644 index 0000000..1cd8bd4 --- /dev/null +++ b/EXAMPLES/rpn.p @@ -0,0 +1,12 @@ +/* a simple RPN calculator */ +#include strtok +#include stack +#include rpnparse + +main() + { + print "Type an expression in Reverse Polish Notation: " + new string[100] + getstring string, sizeof string + rpncalc string + } diff --git a/EXAMPLES/rpnparse.inc b/EXAMPLES/rpnparse.inc new file mode 100644 index 0000000..3896f5d --- /dev/null +++ b/EXAMPLES/rpnparse.inc @@ -0,0 +1,71 @@ +/* main rpn parser and lexical analysis, part of the RPN calculator */ +#include +#include + +enum token + { + t_type, /* operator or token type */ + Rational: t_value, /* value, if t_type is "Number" */ + t_word[20], /* raw string */ + } + +const Number = '0' +const EndOfExpr = '#' + +rpncalc(const string[]) + { + new index + new field[token] + for ( ;; ) + { + field = gettoken(string, index) + switch (field[t_type]) + { + case Number: + push field[t_value] + case '+': + push pop() + pop() + case '-': + push - pop() + pop() + case '*': + push pop() * pop() + case '/', ':': + push 1.0 / pop() * pop() + case EndOfExpr: + break /* exit "for" loop */ + default: + printf "Unknown operator '%s'\n", field[t_word] + } + } + printf "Result = %r\n", pop() + if (clearstack()) + print "Stack not empty\n", red + } + +gettoken(const string[], &index) + { + /* first get the next "word" from the string */ + new word[20] + word = strtok(string, index) + + /* then parse it */ + new field[token] + field[t_word] = word + if (strlen(word) == 0) + { + field[t_type] = EndOfExpr /* special "stop" symbol */ + field[t_value] = 0 + } + else if ('0' <= word[0] <= '9') + { + field[t_type] = Number + field[t_value] = rationalstr(word) + } + else + { + field[t_type] = word[0] + field[t_value] = 0 + } + + return field + } diff --git a/EXAMPLES/set.p b/EXAMPLES/set.p new file mode 100644 index 0000000..3214607 --- /dev/null +++ b/EXAMPLES/set.p @@ -0,0 +1,46 @@ +/* Set operations, using bit arithmetic */ + +main() + { + enum (<<= 1) { A = 1, B, C, D, E, F, G } + new nextstep[] = + { C | E, /* A can reach C and E */ + D | E, /* B " " D and E */ + G, /* C " " G */ + C | F, /* D " " C and F */ + 0, /* E " " none */ + 0, /* F " " none */ + E | F, /* G " " E and F */ + } + #pragma unused A, B + + print "The departure point: " + new start = clamp( .value = toupper(getchar()) - 'A', + .min = 0, + .max = sizeof nextstep - 1 + ) + + print "\nThe number of steps: " + new steps = getvalue() + + /* make the set */ + new result = findtargets(start, steps, nextstep) + printf "The points in range of %c in %d steps: ", start + 'A', steps + for (new i = 0; i < sizeof nextstep; i++) + if (result & 1 << i) + printf "%c ", i + 'A' + } + +findtargets(start, steps, nextstep[], numpoints = sizeof nextstep) + { + new result = 0 + new addedpoints = nextstep[start] + while (steps-- > 0 && result != addedpoints) + { + result = addedpoints + for (new i = 0; i < numpoints; i++) + if (result & 1 << i) + addedpoints |= nextstep[i] + } + return result + } diff --git a/EXAMPLES/sieve.p b/EXAMPLES/sieve.p new file mode 100644 index 0000000..a728a39 --- /dev/null +++ b/EXAMPLES/sieve.p @@ -0,0 +1,16 @@ +/* Print all primes below 100, using the "Sieve of Eratosthenes" */ + +main() + { + const max_primes = 100 + new series[max_primes] = { true, ... } + + for (new i = 2; i < max_primes; ++i) + if (series[i]) + { + printf "%d ", i + /* filter all multiples of this "prime" from the list */ + for (new j = 2 * i; j < max_primes; j += i) + series[j] = false + } + } diff --git a/EXAMPLES/stack.inc b/EXAMPLES/stack.inc new file mode 100644 index 0000000..0123738 --- /dev/null +++ b/EXAMPLES/stack.inc @@ -0,0 +1,26 @@ +/* stack functions, part of the RPN calculator */ +#include + +static Rational: stack[50] +static stackidx = 0 + +push(Rational: value) + { + assert stackidx < sizeof stack + stack[stackidx++] = value + } + +Rational: pop() + { + assert stackidx > 0 + return stack[--stackidx] + } + +clearstack() + { + assert stackidx >= 0 + if (stackidx == 0) + return false + stackidx = 0 + return true + } diff --git a/EXAMPLES/strtok.inc b/EXAMPLES/strtok.inc new file mode 100644 index 0000000..8cf6c9e --- /dev/null +++ b/EXAMPLES/strtok.inc @@ -0,0 +1,25 @@ +/* extract words from a string (words are separated by white space) */ +#include + +strtok(const string[], &index) + { + new length = strlen(string) + + /* skip leading white space */ + while (index < length && string[index] <= ' ') + index++ + + /* store the word letter for letter */ + new offset = index /* save start position of token */ + new result[20] /* string to store the word in */ + while (index < length + && string[index] > ' ' + && index - offset < sizeof result - 1) + { + result[index - offset] = string[index] + index++ + } + result[index - offset] = EOS /* zero-terminate the string */ + + return result + } diff --git a/EXAMPLES/traffic.p b/EXAMPLES/traffic.p new file mode 100644 index 0000000..c975ccd --- /dev/null +++ b/EXAMPLES/traffic.p @@ -0,0 +1,35 @@ +/* traffic light synchronizer, using states in an event-driven model */ +#include