#!/usr/local/bin/kermit ; UNIX: Change previous line to contain full pathname of C-Kermit 7.0 binary. COMMENT - File CKEDEMO.KSC ; ; Exercises Kermit's programming constructs. ; Converted to block-structured format, March 1996. ; Updated to C-Kermit 7.0, April 1999. ; echo If you don't see the message "Proceeding..." echo on the next line, C-Kermit was not configured for script programming. check if echo Proceeding... echo switch \v(program) { :C-Kermit, if ( < \v(version) 70000 ) stop 1 Version 7.0 or later required... echo C-Kermit Programming-Constructs Test break :default stop 1 Sorry - this demo only works with C-Kermit 7.0 or later. } echo echo Defining macros: COMMENT - SPELLNUM macro. ; echo { SPELLNUM} define SPELLNUM { local \%x \&a[] dcl \&a[9] = one two three four five six seven eight nine .\&a[0] = zero if ( not def \%1 ) end 1 .\%1 ::= \%1 if ( < \%1 0 ) { .\%x = { minus} .\%1 ::= 0-\%1 } if ( > \%1 9 ) end 1 { Sorry, too hard} echo \%x \&a[\%1] } COMMENT - CALC macro. "Pocket calculator". No arguments. ; echo { CALC} define CALC { echo Press Return to exit ; Say how to exit. while 1 { ; Loop until they want to exit ask \%1 { expression: } ; Ask for an expression if ( not def \%1 ) break echo \flpad(\feval(\%1),10) ; Evaluate and print answer } echo Back to... ; All done } echo { ADDINGMACHINE} define ADDINGMACHINE { local total \%s \%x echo Type numbers (one per line) or press Return to quit... assign total 0 ; Initialize the sum while true { ; Loop till done askq \%s ; Wait for a number if ( not def \%s ) break ; Return quits loop .\%x ::= \%s if ( not def \%x ) { echo "\%s" invalid - try again, continue } increment total \%x ; Add it to the sum if fail { echo Can't add "\%s", continue } xecho \flpad(\%s,10)\flpad(\m(total),10) ; Print number and subtotal } echo Total\flpad(\m(total),15,.) } COMMENT - SMALLEST macro, recursive. Arguments: ; 1 = a number or expression ; 2 = a number or expression ; 3 = a number or expression ; Prints the smallest of the three. ; echo { SMALLEST} def SMALLEST { local \%a \%i \&a[] dcl \&a[3] if ( != \v(argc) 4 ) end 1 { Sorry - three numbers required.} for \%i 1 3 1 { .\&a[\%i] ::= \&_[\%i] if not numeric \&a[\%i] end 1 { Bad number or expression } } if ( < \&a[1] \&a[2] ) { ; Compare first two arguments echo \&a[1] is less than \&a[2] ; The first one is smaller if ( < \&a[1] \&a[3] ) { ; Compare it with the third echo \&a[1] is less than \&a[3] ; The first one is smaller .\%a := \&a[1] ; Copy it to \%a } else { ; The third is smaller echo \&a[1] is not less than \&a[3] .\%a := \&a[3] ; Copy it to \%a } } else { ; Otherwise echo \&a[1] is not less than \&a[2] ; The second is smaller if ( < \&a[2] \&a[3] ) { ; Compare it with the third echo \&a[2] is less than \&a[3] ; The second is smaller .\%a := \&a[2] ; Copy it to \%a } else { ; The third is smaller echo \&a[2] is not less than \&a[3] .\%a := \&a[3] ; Copy it to \%a } } echo So the smallest is \%a. ; Announce the winner } ec Spelling some numbers... for \%i -5 9 1 { spellnum \%i } echo Calculator demo... calc echo Adding machine demo - Enter an empty line to quit... addingmachine COMMENT - SUM macro, recursive. Argument: ; 1 = limit of sum, a positive number. ; Returns sum of 1 through the number. ; echo { SUM} def SUM { if not def \%1 return ; Make sure there is an argument if not numeric \%1 return ; Make sure argument is numeric if not > \%1 0 return ; Make sure argument is positive if = \%1 1 return 1 ; If argument is 1, the sum is 1 else return \feval(\%1+\fexecute(sum,\feval(\%1-1))) } COMMENT - ADDEMUP macro, for calling SUM. ; echo { ADDEMUP} def ADDEMUP { local total assign total \fexec(sum,\%1) if def total echo SUM(\%1) = \m(total) else echo SUM doesn't work for \%1 } addemup 1 addemup 2 addemup 3 addemup 4 addemup 5 addemup 10 addemup 20 :SMALLEST while true { ask \%x { Type 3 numbers separated by spaces or an empty line to quit: } if not def \%x break smallest \%x } echo WHILE-LOOP TEST... echo You should see: echo { 0 1 2 3 4} def \%a 0 while < \%a 5 { xecho { \%a}, incr \%a } echo echo NESTED WHILE-LOOP TEST... echo You should see: echo { 0:0 0:1 0:2 1:0 1:1 1:2 2:0 2:1 2:2} def \%a 0 while ( < \%a 3 ) { def \%b 0 while ( < \%b 3 ) { xecho { \%a:\%b} incr \%b } incr \%a } echo echo FOR-LOOP INSIDE WHILE-LOOP echo You should see: echo { 1:1 1:2 1:3 2:1 2:2 2:3 3:1 3:2 3:3} def \%a 1 while ( < \%a 4 ) { for \%i 1 3 1 { xecho { \%a:\%i} } inc \%a } echo echo WHILE-LOOP INSIDE FOR-LOOP echo You should see: echo { 1:1 1:2 1:3 2:1 2:2 2:3 3:1 3:2 3:3} for \%i 1 3 1 { .\%a = 1 while < \%a 4 { xecho { \%i:\%a} incr \%a } } echo echo NESTED FOR LOOP TEST echo You should see: echo { 1:1 1:2 1:3 2:2 2:3 3:3} for \%i 1 3 1 { for \%j \%i 3 1 { xecho { \%i:\%j} } } echo echo NESTED FOR/WHILE/BREAK/CONTINUE TEST echo You should see: echo { 1:1 1:3 3:1 3:3} for \%i 1 4 1 { if = \%i 2 continue else if = \%i 4 break asg \%j 0 while < \%j 4 { incr \%j if = \%j 2 continue else if = \%j 4 break xecho { \%i:\%j} } } echo echo END from inside nested FOR loops echo You should see: echo { 1:1 1:2 1:3 2:1 2:2 2:3 3:1} define xx { for \%i 1 3 1 { for \%j 1 3 1 { xecho { \%i:\%j} if = \%i 3 if = \%j 1 end } } } do xx echo echo RETURN from inside nested FOR loops echo You should see "IT WORKS": define xx { local \%i \%j for \%i 1 3 1 { for \%j 1 3 1 { if = \%i 3 if = \%j 1 return IT \%1 } } echo YOU SHOULD NOT SEE THIS } echo "\fexec(xx WORKS)" :IFENDTEST echo END message from inside IF echo You should see "IT WORKS" def xx if = 1 1 { end 0 "IT \%1"} xx WORKS echo Grouping of words in IF EQUAL echo You should see "IT WORKS": def \%a one two three if equal {\%a} {one two three} echo "IT WORKS" else echo It doesn't work, foo. ec echo Use of expressions and braces in FOR-loop variables echo You should see "1 2 3": def \%a 2 for \%i 1 { 1 + \%a } 1 { xecho {\%i } } echo echo A macro that echoes its arguments def XX { local \%i for \%i 1 { \v(argc) - 1 } 1 { echo \%i. "\&_[\%i]" } } while true { ask \%a {Type some words (or just carriage return to quit): } if not def \%a break xx \%a } echo if not eq {\v(connection)} {remote} forward arrays ec MINPUT test... ec Please type one of the following (without the number): ec { 1. ab cd} ec { 2. abcd} ec { 3. xyz} ec You have 10 seconds... minput 10 {ab cd} abcd xyz if success { echo, echo You typed Number \v(minput).} else { echo, echo You did not type any of them within the time limit.} echo :ARRAYS echo ARRAY TEST I (SLOW)... ; Note that there are much better ways to do this. ; Here we're just testing subscript evaluation, looping, etc. ; declare \&a[26] local \%i \%j \%t ; Local variables assign \%i 1 asg \&a[\%i] zebra incr \%i asg \&a[\%i] x-ray incr \%i 1 asg \&a[\%i] baker incr \%i 3-2 asg \&a[\%i] able decr \%i -1 asg \&a[\%i] charlie asg \&a[\%i+1] easy asg \&a[\%i+2] george asg \&a[\%i+3] dog asg \%n \%i+2+8/4 asg \&a[\%n] fox echo Sorting ... for \%i 1 (\%n)-1 1 { ; Outer loop: i from 1 to n-1 for \%j \%i \%n 1 { ; Inner loop: j from i to n if lgt \&a[\%i] \&a[\%j] { ; Compare array elements asg \%t \&a[\%i] ; If out of order, asg \&a[\%i] \&a[\%j] ; exchange them asg \&a[\%j] \%t } } } echo You should see \feval(\%n) words in alphabetical order: for \%i 1 \%n 1 { echo { \%i. \&a[\%i]} } ; All sorted - print them echo echo ARRAY TEST II (FAST)... ; ; Same thing again the easy (and fast) way... ; declare \&a[] = alpha beta gamma delta epsilon zeta eta theta iota echo Sorting ... sort a echo You should see \fdimension(&a) words in alphabetical order: show array a echo exit 0 End of \v(cmdfile)