Author Topic: Nimrod  (Read 44692 times)

Offline John

  • Forum Support / SB Dev
  • Posts: 3510
    • ScriptBasic Open Source Project
Nimrod - Sieve
« Reply #30 on: September 25, 2013, 12:24:05 AM »
Quote
The Sieve of Eratosthenes is a simple algorithm that finds the prime numbers up to a given integer.

Code: [Select]
import math, strutils
 
var is_prime: seq[Bool] = @[]
is_prime.add(False)

iterator iprimes_upto(limit: int): int =
    for n in high(is_prime) .. limit+2: is_prime.add(True)   
    for n in 2 .. limit + 1:
        if is_prime[n]:
            yield n
            for i in countup((n *% n), limit+1, n): # start at ``n`` squared
                try:
                    is_prime[i] = False
                except EInvalidIndex: break
 
 
echo("Primes are:")
for x in iprimes_upto(200):
   write(stdout, x, " ")
writeln(stdout,"")

jrs@laptop:~/nimrod/examples$ nimrod c -d:release sieve.nim
config/nimrod.cfg(36, 11) Hint: added path: '/home/jrs/.babel/libs/' [Path]
Hint: used config file '/home/jrs/nimrod/config/nimrod.cfg' [Conf]
Hint: system [Processing]
Hint: sieve [Processing]
Hint: math [Processing]
Hint: strutils [Processing]
Hint: parseutils [Processing]
gcc -c -w -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o examples/nimcache/sieve.o examples/nimcache/sieve.c
gcc -c -w -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o examples/nimcache/system.o examples/nimcache/system.c
gcc -c -w -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o examples/nimcache/math.o examples/nimcache/math.c
gcc -c -w -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o examples/nimcache/strutils.o examples/nimcache/strutils.c
gcc   -o /home/jrs/nimrod/examples/sieve  examples/nimcache/parseutils.o examples/nimcache/strutils.o examples/nimcache/math.o examples/nimcache/system.o examples/nimcache/sieve.o  -ldl -lm
Hint: operation successful (9489 lines compiled; 1.661 sec total; 11.117MB) [SuccessX]

jrs@laptop:~/nimrod/examples$ time ./sieve
Primes are:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199

real   0m0.002s
user   0m0.000s
sys   0m0.000s
jrs@laptop:~/nimrod/examples$
« Last Edit: September 25, 2013, 12:29:10 AM by John »

Offline Charles Pegge

  • BASIC Developer
  • Posts: 69
Re: Nimrod
« Reply #31 on: September 25, 2013, 02:20:44 AM »
This algorithm is a lot easier to understand when written in basic :)

Code: [Select]
'Sieve of Eratosthenes
includepath "$/inc/"
include "console.inc"
%max 200
sys n[max]
q=0
p=2 'first prime
print "Primes from 2.." & max & chr(13,10)
do
  for i=p*2 to max step p
    n[i]=1 'mark multiples of prime as non-prime
  next
  q=0
  for i=p+1 to max
    if n[i]=0
      q=i 'next prime located
      print i & chr(9)
      exit for
    end if
  next
  if q=0 then exit do 'no more primes
  p=q
end do
WaitKey

Offline John

  • Forum Support / SB Dev
  • Posts: 3510
    • ScriptBasic Open Source Project
Re: Nimrod - Sieve
« Reply #32 on: September 25, 2013, 09:52:19 AM »
Thanks Charles.

The Nimrod Sieve example was from the Rosettacode.org site. The comment was it was based on the Python example there. I noticed what I thought was a typo and removed the duplicate line. With or without the second line it produces the same results.
Code: [Select]
is_prime.add(False)
is_prime.add(False)

When you question if something is a typo or not you need more understandable code. Thanks for your example which did just that.

Update

Quote
Sequences are always indexed with an int starting at position 0.

It seems the two .add lines bumps the sequence position to start at 2. Not sure why it still works starting at 1.

Quote
Iterators look very similar to procedures, but there are several important differences:

    Iterators can only be called from for loops.
    Iterators cannot contain a return statement and procs cannot contain a yield statement.
    Iterators have no implicit result variable.
    Iterators do not support recursion.
« Last Edit: September 25, 2013, 12:25:06 PM by John »

Offline John

  • Forum Support / SB Dev
  • Posts: 3510
    • ScriptBasic Open Source Project
Re: Nimrod - NOT(Gtk3)
« Reply #33 on: September 25, 2013, 07:14:33 PM »
Kent,

Sorry, Gtk3 isn't supported yet with Nimrod.  :'(

Code: [Select]
F:\Nimrod\examples\gtk>ex5
could not import: gtk_signal_connect_full

F:\Nimrod\examples\gtk>

I have both Gtk2 & Gtk3 installed on Ubuntu. I'm not going back to Gtk2 on Windows. (Kludge)

I would use IUP 3.8 and Nimrod before resorting to having to use Gtk2 under Windows.


kryton9

  • Guest
Re: Nimrod
« Reply #34 on: September 25, 2013, 08:00:18 PM »
Thanks for the tip John, will keep that in mind.

Offline John

  • Forum Support / SB Dev
  • Posts: 3510
    • ScriptBasic Open Source Project
Re: Nimrod - Gtk2
« Reply #35 on: September 25, 2013, 10:21:06 PM »
Never say never.  :-*



I was unable to run my compiled version of Aporia for Windows. (can't fine libxml2-2) I only have libxml2 installed. The -2 version is elusive.

Update

I found a libxml2-2.dll but I'm getting the following error when running Aporia.

F:\Nimrod\Aporia>aporia
SIGSEGV: Illegal storage access. (Attempt to read from nil?)

F:\Nimrod\Aporia>
« Last Edit: September 26, 2013, 12:37:26 AM by John »

Offline John

  • Forum Support / SB Dev
  • Posts: 3510
    • ScriptBasic Open Source Project
Re: Nimrod - Aporia Windows
« Reply #36 on: September 26, 2013, 01:22:02 AM »


Bad copy of Gtk2 for Windows.  :(

Quote
The GnuWin project provides Win32-versions of GNU tools, or tools with a similar open source licence. The ports are native ports, that is they rely only on libraries provided with any standard 32-bits MS-Windows operating system, such as MS-Windows 95 / 98 / ME / NT / 2000 / XP / 2003 / Vista. Unlike CygWin or Msys, native ports do not rely on some kind of Unix emulation, so that there is no need to install additional emulation libraries. At present, all developments have been done under MS-Windows-XP, using the Mingw port of the GNU C and C++ (GCC) compilers. Utilities and libraries provided by GnuWin, are used and distributed with packages such as GNU Emacs and KDE-Windows.

GnuWin at SourceForge
« Last Edit: September 26, 2013, 02:10:34 AM by John »

Offline John

  • Forum Support / SB Dev
  • Posts: 3510
    • ScriptBasic Open Source Project
Nimrod - Pyramid of Numbers
« Reply #37 on: September 26, 2013, 06:17:11 PM »
Quote
This puzzle involves a Pascals Triangle, also known as a Pyramid of Numbers.

           [ 151]
          [  ][  ]
        [40][  ][  ]
      [  ][  ][  ][  ]
    [ X][11][ Y][ 4][ Z]

Each brick of the pyramid is the sum of the two bricks situated below it.
Of the three missing numbers at the base of the pyramid, the middle one is the sum of the other two (that is, Y = X + Z).

Code: [Select]
import math, strutils
 
var B_X, B_Y, B_Z : int = 0
 
type
   Block_Value = object
      Known   : int
      X, Y, Z : int
 
let
   X: Block_Value = Block_Value(Known:0, X:1, Y:0, Z:0)
   Y: Block_Value = Block_Value(Known:0, X:0, Y:1, Z:0)
   Z: Block_Value = Block_Value(Known:0, X:0, Y:0, Z:1)
 
proc Add (L : var Block_Value, R : Block_Value) =
   # Symbolically adds one block to another
   L.Known = L.Known + R.Known
   L.X = L.X + R.X - R.Z    # Z is excluded as n(Y - X - Z) = 0
   L.Y = L.Y + R.Y + R.Z
 
proc Add (L: var Block_Value, R: int) =
   # Symbolically adds a value to the block
   L.Known = L.Known + R
 
proc Image (N : Block_Value): string =
   # The block value, when X,Y,Z are known
   result = $(N.Known + N.X * B_X + N.Y * B_Y + N.Z * B_Z)
 
proc Solve_2x2 (A11: int, A12:int, B1:int, A21:int, A22:int, B2: int) =
   # Don't care about things, supposing an integer solution exists
   if A22 == 0:
      B_X = toInt(B2 / A21)
      B_Y = toInt((B1 - (A11*B_X)) / A12)
   else:
      B_X = toInt((B1*A22 - B2*A12) / (A11*A22 - A21*A12))
      B_Y = toInt((B1 - A11*B_X) / A12)
   B_Z = B_Y - B_X
 
var B : array [1..5, array[1..5, Block_Value]]   # The lower triangle contains blocks
 
# The bottom blocks
Add(B[5][1],X)
Add(B[5][2],11)
Add(B[5][3],Y)
Add(B[5][4],4)
Add(B[5][5],Z)
 
# Upward run
for Row in countdown(4,1):
   for Column in 1 .. Row:
      Add (B[Row][Column], B[Row + 1][Column])
      Add (B[Row][Column], B[Row + 1][Column + 1])
 
# Now have known blocks 40=[3][1], 151=[1][1] and Y=X+Z to determine X,Y,Z
Solve_2x2( B[1][1].X,
           B[1][1].Y,
           151 - B[1][1].Known,
           B[3][1].X,
           B[3][1].Y, 
           40 - B[3][1].Known)
 
#Print the results
for Row in 1..5:
   writeln(stdout,"")
   for Column in 1..Row:
      write(stdout, Image(B[Row][Column]), " ")
writeln(stdout,"")

jrs@laptop:~/nimrod/examples$ nimrod c -d:release pon.nim
config/nimrod.cfg(36, 11) Hint: added path: '/home/jrs/.babel/libs/' [Path]
Hint: used config file '/home/jrs/nimrod/config/nimrod.cfg' [Conf]
Hint: system [Processing]
Hint: pon [Processing]
Hint: math [Processing]
Hint: strutils [Processing]
Hint: parseutils [Processing]
gcc -c -w -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o examples/nimcache/pon.o examples/nimcache/pon.c
gcc   -o /home/jrs/nimrod/examples/pon  examples/nimcache/parseutils.o examples/nimcache/strutils.o examples/nimcache/math.o examples/nimcache/system.o examples/nimcache/pon.o  -ldl -lm
Hint: operation successful (9536 lines compiled; 0.314 sec total; 11.117MB) [SuccessX]
jrs@laptop:~/nimrod/examples$ ./pon

151
81 70
40 41 29
16 24 17 12
5 11 13 4 8
jrs@laptop:~/nimrod/examples$

Offline John

  • Forum Support / SB Dev
  • Posts: 3510
    • ScriptBasic Open Source Project
Nimrod - FFI
« Reply #38 on: September 26, 2013, 08:25:33 PM »
This FFI (foreign function interface) example calls the C strcmp (string compare) function at runtime.

Code: [Select]
proc strcmp(a, b: cstring): cint {.importc: "strcmp", nodecl.}
echo strcmp("abc", "def")
echo strcmp("hello", "hello")

jrs@laptop:~/nimrod/examples$ nimrod c -d:release ffi.nim
config/nimrod.cfg(36, 11) Hint: added path: '/home/jrs/.babel/libs/' [Path]
Hint: used config file '/home/jrs/nimrod/config/nimrod.cfg' [Conf]
Hint: system [Processing]
Hint: ffi [Processing]
gcc -c -w -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o examples/nimcache/ffi.o examples/nimcache/ffi.c
gcc -c -w -O3 -fno-strict-aliasing -I/home/jrs/nimrod/lib -o examples/nimcache/system.o examples/nimcache/system.c
gcc   -o /home/jrs/nimrod/examples/ffi  examples/nimcache/system.o examples/nimcache/ffi.o  -ldl
Hint: operation successful (7441 lines compiled; 1.406 sec total; 8.870MB) [SuccessX]

jrs@laptop:~/nimrod/examples$ ./ffi
-1
0
jrs@laptop:~/nimrod/examples$

kryton9

  • Guest
Re: Nimrod
« Reply #39 on: September 27, 2013, 03:04:32 PM »
Thanks for the updates John glad you got it all resolved.

Offline John

  • Forum Support / SB Dev
  • Posts: 3510
    • ScriptBasic Open Source Project
Re: Nimrod
« Reply #40 on: September 28, 2013, 11:11:25 AM »
My hope is that AIR finds some time and shows us an OSX example of Nimrod using ObjectC.

Offline John

  • Forum Support / SB Dev
  • Posts: 3510
    • ScriptBasic Open Source Project
Nimrod - Windows 7
« Reply #41 on: September 28, 2013, 06:06:54 PM »
I was able to get Nimrod going on my Windows 7 64 bit partition.


Offline John

  • Forum Support / SB Dev
  • Posts: 3510
    • ScriptBasic Open Source Project
Nimrod - using C header files
« Reply #42 on: September 28, 2013, 09:17:09 PM »
I notice a cool feature in the Nimrod docs about adding a C header file into your code. It was looking pretty bleak with trying to convert the SB header file to a .nim interface header file. (SB macros always seem to be an issue) I'll post something here if I get it to work.

Quote
Header pragma

The header pragma is very similar to the noDecl pragma: It can be applied to almost any symbol and specifies that it should not be declared and instead the generated code should contain an #include:

Code: [Select]
type
  PFile {.importc: "FILE*", header: "<stdio.h>".} = distinct pointer
    # import C's FILE* type; Nimrod will treat it as a new pointer type

The header pragma always expects a string constant. The string contant contains the header file: As usual for C, a system header file is enclosed in angle brackets: <>. If no angle brackets are given, Nimrod encloses the header file in "" in the generated C code.
« Last Edit: September 28, 2013, 09:18:45 PM by John »

Offline John

  • Forum Support / SB Dev
  • Posts: 3510
    • ScriptBasic Open Source Project
Nimrod - GUI windows manager
« Reply #43 on: September 28, 2013, 10:17:45 PM »


Code: [Select]
import
  gdk2, glib2, gtk2,
  os
 
proc thisDestroy(widget: pWidget, data: pgpointer){.cdecl.} =
  main_quit()
proc thisMax(widget: pWidget, data: pgpointer){.cdecl.} =
  maximize(get_parent_window(widget))
proc thisUnmax(widget: pWidget, data: pgpointer){.cdecl.} =
  unmaximize(get_parent_window(widget))
proc thisIcon(widget: pWidget, data: pgpointer){.cdecl.} =
  iconify(get_parent_window(widget))
proc thisDeicon(widget: pWidget, data: pgpointer){.cdecl.} =
  deiconify(get_parent_window(widget))
proc thisHide(widget: pWidget, data: pgpointer){.cdecl.} =
  hide(get_parent_window(widget))
  sleep(5)
  show(get_parent_window(widget))
 
proc thisShow(widget: pWidget, data: pgpointer){.cdecl.} =
  show(get_parent_window(widget))
 
var isshifted: bool = false
 
proc thisMove(widget: pWidget, data: pgpointer){.cdecl.} =
  var w, h: gint
  get_size(get_parent_window(widget), Addr(w), Addr(h))
  if isshifted:
     move(get_parent_window(widget), w-10, h-10)
  else:
     move(get_parent_window(widget), w+10, h+10)
  isshifted = not isshifted
 
 
nimrod_init()
var window = window_new(gtk2.WINDOW_TOPLEVEL)
discard allow_grow(window)
set_title(window,"Window management")
var stackbox = vbox_new(TRUE, 10)
var bmax = button_new("maximize")
var bunmax = button_new("unmaximize")
var bicon = button_new("iconize")
var bdeicon = button_new("deiconize")
var bhide = button_new("hide")
var bshow = button_new("show")
var bmove = button_new("move")
var bquit = button_new("Quit")
 
pack_start(stackbox, bmax, TRUE, TRUE, 0)
pack_start(stackbox, bunmax, TRUE, TRUE, 0)
pack_start(stackbox, bicon, TRUE, TRUE, 0)
pack_start(stackbox, bdeicon, TRUE, TRUE, 0)
pack_start(stackbox, bhide, TRUE, TRUE, 0)
pack_start(stackbox, bshow, TRUE, TRUE, 0)
pack_start(stackbox, bmove, TRUE, TRUE, 0)
pack_start(stackbox, bquit, TRUE, TRUE, 0)
set_border_width(Window, 5)
add(window, stackbox)
discard signal_connect(window, "destroy",
                   SIGNAL_FUNC(thisDestroy), nil)
 
discard signal_connect(bicon, "clicked",
                   SIGNAL_FUNC(thisIcon), nil)
discard signal_connect(bdeicon, "clicked",
                   SIGNAL_FUNC(thisDeicon), nil)
discard signal_connect(bmax, "clicked",
                   SIGNAL_FUNC(thisMax), nil)
discard signal_connect(bunmax, "clicked",
                   SIGNAL_FUNC(thisUnmax), nil)
discard signal_connect(bhide, "clicked",
                   SIGNAL_FUNC(thisHide), nil)
discard signal_connect(bshow, "clicked",
                   SIGNAL_FUNC(thisShow), nil)
discard signal_connect(bmove, "clicked",
                   SIGNAL_FUNC(thismove), nil)                   
discard signal_connect(bquit, "clicked",
                   SIGNAL_FUNC(thisDestroy), nil)
show_all(window)
main()


Offline John

  • Forum Support / SB Dev
  • Posts: 3510
    • ScriptBasic Open Source Project
Nimrod - POOP
« Reply #44 on: September 28, 2013, 11:29:43 PM »
Quote
Methods

In ordinary object oriented languages, procedures (also called methods) are bound to a class. This has disadvantages:

* Adding a method to a class the programmer has no control over is impossible or needs ugly workarounds.
* Often it is unclear where the method should belong to: is join a string method or an array method?

Nimrod avoids these problems by not assigning methods to a class. All methods in Nimrod are multi-methods. As we will see later, multi-methods are distinguished from procs only for dynamic binding purposes.

Method call syntax

There is a syntactic sugar for calling routines: The syntax obj.method(args) can be used instead of method(obj, args). If there are no remaining arguments, the parentheses can be omitted: obj.len (instead of len(obj)).

This method call syntax is not restricted to objects, it can be used for any type:

Code: [Select]
import strutils

echo("abc".len) # is the same as echo(len("abc"))
echo("abc".toUpper())
echo({'a', 'b', 'c'}.card)
stdout.writeln("Hello") # the same as writeln(stdout, "Hello")

(Another way to look at the method call syntax is that it provides the missing postfix notation.)

Pure  Object Oriented Programming

Code: [Select]
import strutils

stdout.writeln("Give a list of numbers (separated by spaces): ")
stdout.write(stdin.readLine.split.map(parseInt).max.`$`)
stdout.writeln(" is the maximum!")

jrs@laptop:~/nimrod/examples$ ./poop
Give a list of numbers (separated by spaces):
5 1 8 3 7
8 is the maximum!
jrs@laptop:~/nimrod/examples$
« Last Edit: September 29, 2013, 08:52:36 AM by John »