RosettaCodeData/Task/Call-a-foreign-language-fun.../M2000-Interpreter/call-a-foreign-language-fun...

125 lines
5.1 KiB
Plaintext

Module checkit {
Static DisplayOnce=0
N=100000
Read ? N
Form 60
Pen 14
Background { Cls 5}
Cls 5
\\ use f1 do unload lib - because only New statemend unload it
FKEY 1,"save ctst1:new:load ctst1"
\\ We use a function as string container, because c code can easy color decorated in M2000.
Function ccode {
long primes(long a[], long b)
{
long k=2;
long k2,d=2, l, i;
k2=k*k;
if (b>2)
{
if (k2<b)
{
do {
for (l=k2; l<=b; l+=k)
a[l]--;
k++;
while (a[k])
k++;
k2=k*k;
} while (k2<=b);
}
for (i=2;i<=b;i++)
{
if (a[i]==0)
{
a[d]=i ; d++ ;
}
}
}
else {
if (b>1)
{
if (b>2)
{
d=2; a[0]=2; a[1]=3 ;
}
else {
d=1; a[0]=2;
}
}
}
a[b+1]=d;
return 0;
}
}
\\ extract code. &functionname() is a string with the code inside "{ }"
\\ a reference to function actual is code of function in m2000
\\ using Document object we have an easy way to drop paragraphs
document code$=Mid$(&ccode(), 2, len(&ccode())-2)
\\ remove 1st line two times \\ one line for an edit information from interpreter
\\ paragraph$(code$, 1) export paragraph 1st,using third parameter -1 means delete after export.
drop$=paragraph$(code$,1,-1)+paragraph$(code$,1,-1)
If DisplayOnce Else {
Report 2, "c code for primes"
Report code$ \\ report stop after 3/4 of screen lines use. Press spacebar or mouse button to continue
DisplayOnce++
}
\\ dos "del c:\MyName.*", 200;
If not exist("c:\MyName.dll") then {
Report 2, "Now we have to make a dll"
Rem : Load Make \\ we can use a Make.gsb in current folder - this is the user folder for now
Module MAKE ( fname$, code$, timeout ) {
if timeout<1000 then timeout=1000
If left$(fname$,2)="My" Else Error "Not proper name - use 'My' as first two letters"
Print "Delete old files"
try { remove "c:\MyName" }
Dos "del c:\"+fname$+".*", timeout;
Print "Save c file"
Open "c:\"+fname$+".c" for output as F \\ use of non unicode output
Print #F, code$
Close #F
\\ use these two lines for opening dos console and return to M2000 command line
rem : Dos "cd c:\ && gcc -c -DBUILD_DLL "+fname$+".c"
rem : Error "Check for errors"
\\ by default we give a time to process dos command and then continue
Print "make object file"
dos "cd c:\ && gcc -c -DBUILD_DLL "+fname$+".c" , timeout;
if exist("c:\"+fname$+".o") then {
Print "make dll"
dos "cd c:\ && gcc -shared -o "+fname$+".dll "+fname$+".o -Wl,--out-implib,libmessage.a", timeout;
} else Error "No object file - Error"
if not exist("c:\"+fname$+".dll") then Error "No dll - Error"
}
Make "MyName", code$, 1000
}
Declare primes lib c "c:\MyName.primes" {long c, long d} \\ c after lib mean CDecl call
\\ So now we can check error
\\ make a Buffer (add two more longs for any purpose)
Buffer Clear A as Long*(N+2) \\ so A(0) is base address, of an array of 100002 long (unsign for M2000).
\\ profiler enable a timecount
profiler
Call primes(A(0), N)
m=timecount
total=Eval(A,N+1)-2
Clear Yes, No
Print "Press Y or N to display or not the primes"
Repeat {
Yes=keypress(89) : No=Keypress(78)
wait 10
} Until Yes or No
If Yes then {
Form 80,50
Refresh
For i=2 to total+1
Print Eval(A,i),
next i
Print
}
Print format$("Compute {0} primes in range 1 to {1}, in msec:{2:3}", total, N, m)
\\ unload dll, we have to use exactly the same name, as we use it in declare except for last chars ".dll"
remove "c:\MyName"
}
checkit