Heater
Posts: 12628
Joined: Tue Jul 17, 2012 3:02 pm

Re: ScriptBasic

Fri May 24, 2019 9:20 am

Purely for amusement I have sometimes pondered "data as code" in C as well. Here is the plan I cam up with:

A simple way to have code as data in C is to hold it in a string for example.

char source[] = "double someFunc (double x) { return 1 / sin(x)}";

We could write a function that spawns GCC to compile that string (having written it to a file first) into a dynamically loadable library.

char* libFileName = compile (source);

Then use the dynamic loader to load that library and get a pointer to the code:

void* ptr = load (libFileName);

Then we have a pointer that we can cast to a function type and call it. We could wrap all that up as something like:

double result = eval(source)

BINGO, we can create our own C code dynamically and run it.

To make this into proper data we would need to be able to modify it. For example we might want to change "sin" to "cos" above. That would require we parse that string into some data structure, change the sin to a cos in that data structure, then collapse the data structure back into a string which we could then run again with the above mechanism.

But wait, all that sounds like the front end of GCC or LLVM parsing C into an abstract syntax tree. Tweaking the AST, then generating code from it.

Hmm...OK, we can link our program against all the LLVM libraries and make use of their functionality to do all this....

All of which would be clunky and slow as hell.

User avatar
rpdom
Posts: 14417
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: ScriptBasic

Fri May 24, 2019 10:06 am

RichardRussell wrote:
Fri May 24, 2019 9:03 am
Heater wrote:
Fri May 24, 2019 8:13 am
Of course all this awesome power of first class functions can lead to code that us mortals have trouble understanding...Throw in some closures and recursion and there is no chance.
I had some fun, many years ago, writing a BBC BASIC program that would implement the Rosetta Code First-class functions task. As it states in the comment, strictly speaking you cannot return a function in BBC BASIC (although you could return the code of a function in a string) so I return a function pointer instead, which you may consider to be cheating.

But it does demonstrate what can be achieved when the language provides low-level memory access (by means of indirection in the case of BBC BASIC) and can dynamically create new functions at run-time that way. My OOP library for BBC BASIC for Windows (CLASSLIB.BBC) is entirely reliant on that capability.
When I was working on real BBC Micros a friend of mine came up with a way of loading dynamic procedures. Basically he put something liek the following code at the end of the normal program

Code: Select all

DEF PROC entry
ENDPROC
and moved the memory pointer (was it HIMEM?) to allow for a chunk of free space at the end of the program.
He then loaded more code as needed at the same memory address as the "DEF PROC entry" line and it took over from the original dummy entry.

I didn't use that code. I re-wrote a lot of stuff in assembler and had routines that could be loaded in at a fixed memory address with a jump table at the start. Much faster. I modified one program to run in seconds instead of tens of minutes :)

Heater
Posts: 12628
Joined: Tue Jul 17, 2012 3:02 pm

Re: ScriptBasic

Fri May 24, 2019 12:07 pm

That is amazing Richard.

I think it's stretching it a bit to call it "first class functions". If I understand your code it's storing and passing pointers to functions around. Like the C example on that Rosetta page does. If pointers are first class data types in the language that indirection makes the functions second class.

Also the what about returning a function that was not obtained from outside, not a global function or passed in as a parameter?

Still, it's amazing what we all get done without such features in our languages!

hippy
Posts: 5335
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: ScriptBasic

Fri May 24, 2019 12:20 pm

ScriptBasic wrote:
Thu May 23, 2019 4:17 pm
I wonder what happened to Heater? He seems to have gone silent.
Do you see what you did there ?

Invited 20-plus pretty much off-topic postings into this thread.

With a pretty good chance that saying this will be taken as an opportunity to dispute that with the end result being it goes even further off topic.

Heater
Posts: 12628
Joined: Tue Jul 17, 2012 3:02 pm

Re: ScriptBasic

Fri May 24, 2019 12:35 pm

hippy,
Invited 20-plus pretty much off-topic postings into this thread.
With all due respect, who asked you?

The host of this thread is ScriptBasic and the topic is ScriptBasic.

I asked SciptBasic a question about the Lisp/Scheme in his ScriptBasic.

Then came a chat about Scheme and passing functions around in ScriptBasic with our host.

That is hardly not being "invited".

Anyway, I take your point, it's all straying off topic. I will desist.

User avatar
RichardRussell
Posts: 500
Joined: Thu Jun 21, 2012 10:48 am

Re: ScriptBasic

Fri May 24, 2019 1:02 pm

Heater wrote:
Fri May 24, 2019 12:07 pm
I think it's stretching it a bit to call it "first class functions".
Probably. Using the Rosetta Code definition, my program does achieve the required functionality (creating a composite function at run-time).
If I understand your code it's storing and passing pointers to functions around.
The principal aspect is creating a new function from scratch at run time, not so much the pointer passing.
Also the what about returning a function that was not obtained from outside, not a global function or passed in as a parameter?
Do you mean creating a composite function incorporating one of the built-in functions? That would be possible using the same technique.

User avatar
ScriptBasic
Posts: 1231
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: ScriptBasic

Fri May 24, 2019 2:36 pm

@hippy,

My interest is getting the GPIO extension module going. I should know better what happens when spending too much time at the water cooler with these guys.

@Heater,

The TinyScheme issue is back burner for me right now and I will try to update the library when I have time to see if your fibo(70) returns a correct answer.

@Richard,

I appreciate your feedback and having someone with your skill level as a BASIC developer here is an honor. If you see one of your posts about BBC BASIC forming a new topic direction, please pick it up on your BBC BASIC thread.

User avatar
ScriptBasic
Posts: 1231
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: ScriptBasic

Fri May 24, 2019 11:46 pm

@Heater,

TinyScheme is at its latest level and your script produces the same result in the standalone console version of TinyScheme. It hasn't been updated in 5 years. I think I need to find a better library.

ELK looks like a nice library. The API seems like you have much more control from C then the TinyScheme API.
Image

What is Elk?
------------

Elk is an implementation of the Scheme programming language.
In contrast to existing, stand-alone Scheme systems Elk has been
designed specifically as an embeddable, reusable extension language
subsystem for applications written in C or C++.

Developers using Elk can deliver applications with different components
written in different languages, such as an efficient core written in
C or C++ and an extensible user interface layer implemented in Scheme.
To help building hybrid application architectures, Elk supports a
tightly-knit interworking of the C/C++ parts of applications with
Scheme code.

Elk is also useful as a stand-alone Scheme implementation, in particular
as a platform for rapid prototyping of X11-based Scheme programs.

The Elk project was started in 1987 to support ISOTEXT, a multimedia
document editor that has been developed at the Technical University of
Berlin. The first freely available version, Elk 1.0, was published in
USENET in September 1989. Since then, Elk has been successfully used as
the extension language framework for numerous applications (commercial
products as well as free software projects).
Elk Include

BIGNUM Support!
/* Bignums
*/
extern Object Make_Uninitialized_Bignum (int);
extern void Bignum_Normalize_In_Place (struct S_Bignum *);
extern double Bignum_To_Double (Object);
I would be willing to assist in a elk ScriptBasic extension module if you take the lead.

If you're not interested in elk maybe @ejolson would be?

Code: Select all

(define fibo (lambda (n)
    (let ((alpha (/  (+ 1 (sqrt 5)) 2) )
           (beta (/  (- 1 (sqrt 5)) 2) ))

      (round (- (* (/ 1 (sqrt 5)) (expt alpha n))
                (* (/ 1 (sqrt 5)) (expt beta n)))))))

(display (fibo 70))
(newline)


[email protected]:~/sbrpi/examples $ time elk -l fibo.scm
190392490709135.0

real	0m0.012s
user	0m0.012s
sys	0m0.000s
[email protected]:~/sbrpi/examples $ 
Last edited by ScriptBasic on Sat May 25, 2019 7:43 pm, edited 10 times in total.

User avatar
ScriptBasic
Posts: 1231
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: ScriptBasic

Sat May 25, 2019 2:52 pm

@hippy,,

How is the GPIO extension module going?

hippy
Posts: 5335
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: ScriptBasic

Sat May 25, 2019 10:00 pm

I've been busy spinning other plates which I've had on hold; getting ESP32's to work, building hardware, setting up new Pi's. What I currently have as far as a GPIO library goes is working as far as it's been tested but there is more to do. It gets quite wearing moving between Windows / Linux / Python 2 / Python 3 / ScriptBasic / C so could do with some time away from it to just calmly reflect on what's next and to avoid burnout.

Best bet if you want to move on in parallel is to use what you have. That looked okay when I scanned through it. Make the actual device drivers include the GPIO library, or inherit from it, so you only need to change names of the module and/or methods if things do change.

User avatar
ScriptBasic
Posts: 1231
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: ScriptBasic

Sat May 25, 2019 10:21 pm

If you can merge in what you have to get something going, that would be great. I only created this module at your recommendation to get us started. I'm not interested in doing parallel projects.

I have.little understanding how GPIO works. I'm trying to learn from you.

The GPIO extension I put together is what percent usable?

THIS is the sensor kit I have that I would like to use with the ScriptBasic GPIO extension module.

User avatar
ScriptBasic
Posts: 1231
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: ScriptBasic

Sun May 26, 2019 3:56 am

This is an example C interface for the DHT11 temperature and humidity sensor using WiringPi.

Code: Select all

/*
 *  dht11.c:
 *	Simple test program to test the wiringPi functions
 *	DHT11 test
 */

#include <wiringPi.h>

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define MAXTIMINGS	85
#define DHTPIN		15
int dht11_dat[5] = { 0, 0, 0, 0, 0 };

void read_dht11_dat()
{
	uint8_t laststate	= HIGH;
	uint8_t counter		= 0;
	uint8_t j		= 0, i;
	float	f; /* fahrenheit */

	dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0;

	/* pull pin down for 18 milliseconds */
	pinMode( DHTPIN, OUTPUT );
	digitalWrite( DHTPIN, LOW );
	delay( 18 );
	/* then pull it up for 40 microseconds */
	digitalWrite( DHTPIN, HIGH );
	delayMicroseconds( 40 );
	/* prepare to read the pin */
	pinMode( DHTPIN, INPUT );

	/* detect change and read data */
	for ( i = 0; i < MAXTIMINGS; i++ )
	{
		counter = 0;
		while ( digitalRead( DHTPIN ) == laststate )
		{
			counter++;
			delayMicroseconds( 1 );
			if ( counter == 255 )
			{
				break;
			}
		}
		laststate = digitalRead( DHTPIN );

		if ( counter == 255 )
			break;

		/* ignore first 3 transitions */
		if ( (i >= 4) && (i % 2 == 0) )
		{
			/* shove each bit into the storage bytes */
			dht11_dat[j / 8] <<= 1;
			if ( counter > 16 )
				dht11_dat[j / 8] |= 1;
			j++;
		}
	}

	/*
	 * check we read 40 bits (8bit x 5 ) + verify checksum in the last byte
	 * print it out if data is good
	 */
	if ( (j >= 40) &&
	     (dht11_dat[4] == ( (dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF) ) )
	{
		f = dht11_dat[2] * 9. / 5. + 32;
		printf( "Humidity = %d.%d %% Temperature = %d.%d *C (%.1f *F)\n",
			dht11_dat[0], dht11_dat[1], dht11_dat[2], dht11_dat[3], f );
	}else  {
		printf( "Data not good, skip\n" );
	}
}

int main( void )
{
	printf( "Raspberry Pi wiringPi DHT11 Temperature test program\n" );

	if ( wiringPiSetup() == -1 )
		exit( 1 );

	while ( 1 )
	{
		read_dht11_dat();
		delay( 1000 ); /* wait 1sec to refresh */
	}

	return(0);
}

jamesh
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 22684
Joined: Sat Jul 30, 2011 7:41 pm

Re: ScriptBasic

Sun May 26, 2019 7:44 am

ScriptBasic wrote:
Sun May 26, 2019 3:56 am
This is an example C interface for the DHT11 temperature and humidity sensor using WiringPi.

Code: Select all

/*
 *  dht11.c:
 *	Simple test program to test the wiringPi functions
 *	DHT11 test
 */

#include <wiringPi.h>

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define MAXTIMINGS	85
#define DHTPIN		15
int dht11_dat[5] = { 0, 0, 0, 0, 0 };

void read_dht11_dat()
{
	uint8_t laststate	= HIGH;
	uint8_t counter		= 0;
	uint8_t j		= 0, i;
	float	f; /* fahrenheit */

	dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0;

	/* pull pin down for 18 milliseconds */
	pinMode( DHTPIN, OUTPUT );
	digitalWrite( DHTPIN, LOW );
	delay( 18 );
	/* then pull it up for 40 microseconds */
	digitalWrite( DHTPIN, HIGH );
	delayMicroseconds( 40 );
	/* prepare to read the pin */
	pinMode( DHTPIN, INPUT );

	/* detect change and read data */
	for ( i = 0; i < MAXTIMINGS; i++ )
	{
		counter = 0;
		while ( digitalRead( DHTPIN ) == laststate )
		{
			counter++;
			delayMicroseconds( 1 );
			if ( counter == 255 )
			{
				break;
			}
		}
		laststate = digitalRead( DHTPIN );

		if ( counter == 255 )
			break;

		/* ignore first 3 transitions */
		if ( (i >= 4) && (i % 2 == 0) )
		{
			/* shove each bit into the storage bytes */
			dht11_dat[j / 8] <<= 1;
			if ( counter > 16 )
				dht11_dat[j / 8] |= 1;
			j++;
		}
	}

	/*
	 * check we read 40 bits (8bit x 5 ) + verify checksum in the last byte
	 * print it out if data is good
	 */
	if ( (j >= 40) &&
	     (dht11_dat[4] == ( (dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF) ) )
	{
		f = dht11_dat[2] * 9. / 5. + 32;
		printf( "Humidity = %d.%d %% Temperature = %d.%d *C (%.1f *F)\n",
			dht11_dat[0], dht11_dat[1], dht11_dat[2], dht11_dat[3], f );
	}else  {
		printf( "Data not good, skip\n" );
	}
}

int main( void )
{
	printf( "Raspberry Pi wiringPi DHT11 Temperature test program\n" );

	if ( wiringPiSetup() == -1 )
		exit( 1 );

	while ( 1 )
	{
		read_dht11_dat();
		delay( 1000 ); /* wait 1sec to refresh */
	}

	return(0);
}
Please include attribution when posting other people's code. It's only polite.
Principal Software Engineer at Raspberry Pi (Trading) Ltd.
Contrary to popular belief, humorous signatures are allowed. Here's an example...
"My grief counseller just died, luckily, he was so good, I didn't care."

User avatar
ScriptBasic
Posts: 1231
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: ScriptBasic

Sun May 26, 2019 2:25 pm

This code is from the Kookye sensor kit I bought and referenced in the THIS link above. I agree with your point.

Kookye Senor Kit Tutorials

@JamesH,

Any chance you would be interested in taking the lead with the new Elk extension module?

ScriptBasic is the Heathkit of scripting languages.
Last edited by ScriptBasic on Sun May 26, 2019 5:47 pm, edited 3 times in total.

hippy
Posts: 5335
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: ScriptBasic

Sun May 26, 2019 2:53 pm

ScriptBasic wrote:
Sat May 25, 2019 10:21 pm
If you can merge in what you have to get something going, that would be great. I only created this module at your recommendation to get us started. I'm not interested in doing parallel projects.
I guess this is always a problem where there's no originally co-ordinated effort, where projects collide rather than being intended to be a whole from the start.

I'm really only interested in getting my Python code sending to a graphic LCD at a reasonably fast speed, and to that end decided to craft my own GPIO extension module which would work in the way I wanted it to rather than the way anyone else's did. And, further to that, I wrote an extension module creation tool so I did not need to code that by hand, which could be used in the future and for other Python variants.

With your own GPIO efforts I noted some things could be improved and also suggested my creation program could be made to produce ScriptBasic extension modules. That seemed like a good idea to put it through its paces and the extension would also benefit from others testing it out. That's taken longer to do and get right than anticipated but I seem to be almost there.

Most of the effort has been in getting the creation program working. Creating the 'for Python' code I desire and figuring out what ScriptBasic needs, making it produce that, making that build. Alongside that, getting the extension fit for purpose and testing that.

There's still some work to do, but as a basic extension it is done. So the best thing is probably to post what I have. I'll do that soon.
ScriptBasic wrote:
Sat May 25, 2019 10:21 pm
The GPIO extension I put together is what percent usable?
I would guess all of it but I haven't tested any of it.

User avatar
ScriptBasic
Posts: 1231
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: ScriptBasic

Sun May 26, 2019 3:00 pm

Thanks for the update!

Remember, you're driving and I'm along for the ride.

hippy
Posts: 5335
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: ScriptBasic

Sun May 26, 2019 3:09 pm

ScriptBasic wrote:
Sun May 26, 2019 3:00 pm
Remember, you're driving and I'm along for the ride.
But do remember that offering a suggestion, or being willing to drive someone to an airport, doesn't mean accepting responsibility for someone else's holiday 8-)

User avatar
ScriptBasic
Posts: 1231
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: ScriptBasic

Sun May 26, 2019 3:15 pm

I'll cover my own expenses. 🤗

The JAPI extension module author also created a generic SB ext. module builder that's pretty cool and worth a peek.

JAPI SB Template

interface.c (CallByName) engine
Last edited by ScriptBasic on Sun May 26, 2019 8:17 pm, edited 3 times in total.

jalih
Posts: 60
Joined: Mon Apr 15, 2019 3:54 pm

Re: ScriptBasic

Sun May 26, 2019 6:13 pm

ScriptBasic wrote:
Sun May 26, 2019 3:56 am
This is an example C interface for the DHT11 temperature and humidity sensor using WiringPi.
Looks like that sample would only need support for minimal GPIO functionality. Handling micro seconds delays seems to be the only thing that I would need to implement for 8th programming language conversion. I guess polling and using high-resolution timer is the only possibility for such a short delays.

User avatar
ScriptBasic
Posts: 1231
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: ScriptBasic

Sun May 26, 2019 6:40 pm

Until I see a sensor working using SB, I'm in the front row of @hippy's GPIO class.🤪

User avatar
ScriptBasic
Posts: 1231
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: ScriptBasic

Mon May 27, 2019 5:26 am

@hippy,

The pigpio library is a socket interface. ScriptBasic has built in socket support. Do you think it's feasible to write a native SB interface (no ext. module) to pigpio?

hippy
Posts: 5335
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: ScriptBasic

Mon May 27, 2019 10:40 am

ScriptBasic wrote:
Mon May 27, 2019 5:26 am
The pigpio library is a socket interface. ScriptBasic has built in socket support. Do you think it's feasible to write a native SB interface (no ext. module) to pigpio?
I have never looked at pigpio. I would guess it's possible looking at the Python Wrapper but I wouldn't have thought there would be much difference between importing an extension or including a set of routines other than the language used to write that.

There are advantages to using a networked service for GPIO, not least that a program can be directed to control something elsewhere. I would probably write a native GPIO extension, then add a means of vectoring that elsewhere, to pigpiod etc.

To be honest; all these GPIO schemes, extensions and libraries are 'paths to nowhere' long term. The future seems to be 'gpiolib' which offers a managed GPIO layer handled by the kernel. That's been there since the 4.8 Kernel and the Pi seems to support that though Raspbian doesn't offer the userland support utilities. The sysfs approach has long been deprecated and direct register access is just a downright wrong approach.

Extensions and libraries will retain a use, if only to abstract how they do things now to how it's done in the future. That abstraction is why we use extensions and libraries; it maintains backwards compatibility even if the 'how it works' fundamentally changes.

In that respect Python and other interpretive language users are likely better protected from change than C and C++ programmers ( including extension writers ) who have been misdirected into using direct register access for GPIO.

User avatar
ScriptBasic
Posts: 1231
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: ScriptBasic

Mon May 27, 2019 3:14 pm

Thanks for the feedback and info about GPIO under the covers. This is new territory for me so I'm all ears.

I'm curious what is missing with the GPIO extension I posted to start accessing my sensor kit? I would like to try accessing the DHT11 Temp / Humidity sensor to start.

Did you checkout the JAPI extension module interface? Interesting approach.

hippy
Posts: 5335
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: ScriptBasic

Mon May 27, 2019 6:48 pm

ScriptBasic wrote:
Mon May 27, 2019 3:14 pm
I'm curious what is missing with the GPIO extension I posted to start accessing my sensor kit?
No idea ! My initial comments I recall were merely suggestions, such as making names more user friendly and their purpose more obvious, such as "setAltFunction()" rather than "setup_gpio()", and removing any "gpio_" prefix, for example there's no need for, "GPIO::gpio_input(0)" when it's purpose is in the "GPIO" name; "GPIO::input(0)".

If it's call all the main primitives, set Alt function, set output to a level, read input pin level, set pull-up and pull-down, it should be usable for most GPIO stuff.

My additions have been to make things safer, not allowing access to random pins by accident, then extending the primitives to add things like bit-banged SPI and I2C. Plus some hoop-jumping so I can have my Python code look like this with auto clean-up when done -

Code: Select all

import GPIO
with GPIO() as gpio:
  pin = 0
  gpio.GPSET0 = 1 << pin
  gpio.GPCLR0 = 1 << pin
ScriptBasic wrote:
Mon May 27, 2019 3:14 pm
Did you checkout the JAPI extension module interface? Interesting approach.
I had a look through it. Apart from that using the older interface style it seems to be very similar to the way I am doing things.

User avatar
ScriptBasic
Posts: 1231
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: ScriptBasic

Mon May 27, 2019 6:57 pm

If it's call all the main primitives, set Alt function, set output to a level, read input pin level, set pull-up and pull-down, it should be usable for most GPIO stuff.
Would you be so kind to post a ScriptBasic example using the GPIO extension module I have? Once I see the basic functionality working I can expand on it for other sensors.

Return to “Other programming languages”