<commit_before>/***
	bitlash-functions.c

	Bitlash is a tiny language interpreter that provides a serial port shell environment
	for bit banging and hardware hacking.

	Bitlash lives at: http://bitlash.net
	The author can be reached at: <EMAIL>

	Copyright (C) 2008, 2009, 2010 <NAME>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

***/
#include "bitlash.h"

// syntactic sugar for func_handlers()
extern numvar getarg(numvar);
#define arg1 getarg(1)
#define arg2 getarg(2)
#define arg3 getarg(3)
#define arg4 getarg(4)
#define arg5 getarg(5)

///////////////////////
// FUNCTION HANDLERS
//

// The native tone() routine first included in Arduino 0018 is quite large, 
//		about 1k differential: 15196 - 14110
// It is, however, for the moment quite a bit more frequency-accurate
//
//#define USE_NATIVE_TONE
#ifdef USE_NATIVE_TONE
void beep(unumvar pin, unumvar frequency, unumvar duration) {
	tone(pin, frequency, duration);
	delay(duration);
}
#else
numvar func_beep(void) { 		// unumvar pin, unumvar frequency, unumvar duration)
	unsigned long cycles = ((unsigned long) arg2 * (unsigned long) arg3) / 1000UL;
	unsigned long halfperiod = (500000UL / (unsigned long) arg2) - 7UL;	// 7 fudge

	// todo: check for break in here?  This could go 32 seconds...
	pinMode(arg1, OUTPUT);
	while (cycles--) {
		digitalWrite(arg1, HIGH);
		delayMicroseconds(halfperiod);
		digitalWrite(arg1, LOW);
		delayMicroseconds(halfperiod-1);
	}
}
#endif

numvar func_free(void) {
numvar ret;
	// from http://forum.pololu.com/viewtopic.php?f=10&t=989&view=unread#p4218
	extern int __bss_end;
	return ((int)&ret) - ((int)&__bss_end);
}


///////////////////////////////////////////////
//	Dead Beef Random Number Generator
//	from http://inglorion.net/software/deadbeef_rand/
//	stated license terms: "Feel free to use the code in your own software."
///////////////////////////////////////////////
//
static uint32_t deadbeef_seed = 0xbeefcafe;
static uint32_t deadbeef_beef = 0xdeadbeef;
numvar func_random(void) {
unumvar ret;
	deadbeef_seed = (deadbeef_seed << 7) ^ ((deadbeef_seed >> 25) + deadbeef_beef);
	ret = ((numvar) deadbeef_seed & 0x7fff) % arg1;
	deadbeef_beef = (deadbeef_beef << 7) ^ ((deadbeef_beef >> 25) + 0xdeadbeef);
	return ret;
}

// add entropy to the pool
void stir(byte trash) {
	deadbeef_seed ^= 1 << (trash & 0x1f);
}

#if 0
// seed the random number generator
void dbseed(uint32_t x) {
	deadbeef_seed = x;
	deadbeef_beef = 0xdeadbeef;
}
#endif


/////////////////////////////////////////
// memory mapped port io: inb() and outb()
//
//	see the table of register addresses on page 203 of the Tiny85 spec
//	it is necessary to add 0x20 to the address in the "register" column
//	to get the proper mapped address for the register
//		thus: TCCR0B assigned 0x33 is accesssible at 0x53
//		>print inb(0x53)
//		2
//
numvar func_inb(void) { return *(volatile byte *) arg1; }
numvar func_outb(void) { *(volatile byte *) arg1 = (byte) arg2; }
numvar func_abs(void) { return arg1 < 0 ? -arg1 : arg1; }
numvar func_sign(void) {
	if (arg1 < 0) return -1;
	if (arg1 > 0) return 1;
	return 0;
}
numvar func_min(void) { return (arg1 < arg2) ? arg1 : arg2; }
numvar func_max() { return (arg1 > arg2) ? arg1 : arg2; }
numvar func_constrain(void) {
	if (arg1 < arg2) return arg2;
	if (arg1 > arg3) return arg3;
	return arg1;
}
numvar func_ar(void) { return analogRead(arg1); }
numvar func_aw(void) { analogWrite(arg1, arg2); return 0; }
numvar func_dr(void) { return digitalRead(arg1); }
numvar func_dw(void) { digitalWrite(arg1, arg2); return 0; }
numvar func_er(void) { return eeread(arg1); }
numvar func_ew(void) { eewrite(arg1, arg2); return 0; }
numvar func_pinmode(void) { pinMode(arg1, arg2); return 0; }
numvar func_pulsein(void) { return pulseIn(arg1, arg2, arg3); }
numvar func_snooze(void) { snooze(arg1); return 0; }
numvar func_delay(void) { delay(arg1); return 0; }
numvar func_setBaud(void) { setBaud(arg1, arg2); return 0; }

//////////
// Function name dictionary
//
// Function dispatch is accomplished by looking up the proposed function name in this structure, 
// which must be in ascending alphabetical order.
//
// The index at which a matching function name is found is used to reference 
// the function_table defined below to get the argument signature and C function 
// address for the handler.<commit_msg>args wip working with bugs<commit_after>/***
	bitlash-functions.c

	Bitlash is a tiny language interpreter that provides a serial port shell environment
	for bit banging and hardware hacking.

	Bitlash lives at: http://bitlash.net
	The author can be reached at: <EMAIL>

	Copyright (C) 2008, 2009, 2010 <NAME>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

***/
#include "bitlash.h"

// syntactic sugar for func_handlers()
extern numvar getarg(numvar);
#if 0	// 15022 bytes
#define arg1 getarg(1)
#define arg2 getarg(2)
#define arg3 getarg(3)
#endif

// 14772 vs 15022
extern numvar *arg;
#define arg1 arg[1]
#define arg2 arg[2]
#define arg3 arg[3]
void req1arg(void)  { if (arg[0] != 1) missing(M_arg); }
void req2args(void) { if (arg[0] != 2) missing(M_arg); }
void req3args(void) { if (arg[0] != 3) missing(M_arg); }


///////////////////////
// FUNCTION HANDLERS
//

// The native tone() routine first included in Arduino 0018 is quite large, 
//		about 1k differential: 15196 - 14110
// It is, however, for the moment quite a bit more frequency-accurate
//
//#define USE_NATIVE_TONE
#ifdef USE_NATIVE_TONE
void beep(unumvar pin, unumvar frequency, unumvar duration) {
	tone(pin, frequency, duration);
	delay(duration);
}
#else
numvar func_beep(void) { 		// unumvar pin, unumvar frequency, unumvar duration)
	req3args();
	unsigned long cycles = ((unsigned long) arg2 * (unsigned long) arg3) / 1000UL;
	unsigned long halfperiod = (500000UL / (unsigned long) arg2) - 7UL;	// 7 fudge

	// todo: check for break in here?  This could go 32 seconds...
	pinMode(arg1, OUTPUT);
	while (cycles--) {
		digitalWrite(arg1, HIGH);
		delayMicroseconds(halfperiod);
		digitalWrite(arg1, LOW);
		delayMicroseconds(halfperiod-1);
	}
}
#endif

numvar func_free(void) {
numvar ret;
	// from http://forum.pololu.com/viewtopic.php?f=10&t=989&view=unread#p4218
	extern int __bss_end;
	return ((int)&ret) - ((int)&__bss_end);
}


///////////////////////////////////////////////
//	Dead Beef Random Number Generator
//	from http://inglorion.net/software/deadbeef_rand/
//	stated license terms: "Feel free to use the code in your own software."
///////////////////////////////////////////////
//
static uint32_t deadbeef_seed = 0xbeefcafe;
static uint32_t deadbeef_beef = 0xdeadbeef;
numvar func_random(void) {
unumvar ret;
	req1arg();
	deadbeef_seed = (deadbeef_seed << 7) ^ ((deadbeef_seed >> 25) + deadbeef_beef);
	ret = ((numvar) deadbeef_seed & 0x7fff) % arg1;
	deadbeef_beef = (deadbeef_beef << 7) ^ ((deadbeef_beef >> 25) + 0xdeadbeef);
	return ret;
}

// add entropy to the pool
void stir(byte trash) {
	deadbeef_seed ^= 1 << (trash & 0x1f);
}

#if 0
// seed the random number generator
void dbseed(uint32_t x) {
	deadbeef_seed = x;
	deadbeef_beef = 0xdeadbeef;
}
#endif


/////////////////////////////////////////
// memory mapped port io: inb() and outb()
//
//	see the table of register addresses on page 203 of the Tiny85 spec
//	it is necessary to add 0x20 to the address in the "register" column
//	to get the proper mapped address for the register
//		thus: TCCR0B assigned 0x33 is accesssible at 0x53
//		>print inb(0x53)
//		2
//
numvar func_inb(void) { req1arg(); return *(volatile byte *) arg1; }
numvar func_outb(void) { req2args(); *(volatile byte *) arg1 = (byte) arg2; }
numvar func_abs(void) { req1arg(); return arg1 < 0 ? -arg1 : arg1; }
numvar func_sign(void) {
	req1arg();
	if (arg1 < 0) return -1;
	if (arg1 > 0) return 1;
	return 0;
}
numvar func_min(void) { req2args(); return (arg1 < arg2) ? arg1 : arg2; }
numvar func_max() { req2args(); return (arg1 > arg2) ? arg1 : arg2; }
numvar func_constrain(void) {
	req3args();
	if (arg1 < arg2) return arg2;
	if (arg1 > arg3) return arg3;
	return arg1;
}
numvar func_ar(void) { req1arg(); return analogRead(arg1); }
numvar func_aw(void) { req2args(); analogWrite(arg1, arg2); return 0; }
numvar func_dr(void) { req1arg(); return digitalRead(arg1); }
numvar func_dw(void) { req2args(); digitalWrite(arg1, arg2); return 0; }
numvar func_er(void) { req1arg(); return eeread(arg1); }
numvar func_ew(void) { req2args(); eewrite(arg1, arg2); return 0; }
numvar func_pinmode(void) { req2args(); pinMode(arg1, arg2); return 0; }
numvar func_pulsein(void) { req3args(); return pulseIn(arg1, arg2, arg3); }
numvar func_snooze(void) { req1arg(); snooze(arg1); return 0; }
numvar func_delay(void) { req1arg(); delay(arg1); return 0; }
numvar func_setBaud(void) { req2args(); setBaud(arg1, arg2); return 0; }

//////////
// Function name dictionary
//
// Function dispatch is accomplished by looking up the proposed function name in this structure, 
// which must be in ascending alphabetical order.
//
// The index at which a matching function name is found is used to reference 
// the function_table defined below to get the argument signature and C function 
// address for the handler.
{'fraction_non_alphanumeric': 0.14008518693800284, 'fraction_numerical': 0.03776620918125887, 'mean_word_length': 3.5484287559190704, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6239150', 'n_tokens_mistral': 3804, 'n_tokens_neox': 3525, 'n_words': 1237}