Saturday, January 16, 2010

Here's some code I've been playing with as part of that odd language concept. It converts binary, decimal or hex #'s and is 180-300 bytes -Os depending on CPU.

thumb2 really is small - it comes out about 70 bytes shorter than x86. Good for when this code's running on -m3.

It has error but not overflow checking and is written to work at native word size.

Hoping I can get my language running on the AVR as well eventually - ideally I'd have the core running in 2-4K as a bootloader. For some things there's nothing cooler than an 8 or 20-pin DIP chip. . o O (for everything else, there's master^WARM)


/* This flexible parser handles sign, dec, and hex bases while maintaining error checking */

/* Slightly less than 256 bytes on i386 when compiled -Os, slightly more on ARM non-thumb.
* That might still be a bit large. */

int parsenum(char *s, int len, unsigned int *o)
{
int first = 0, i;
int base = 10, m = 1, v;
char cc;

/* one can still handle full unsigned words and have a negative multiplier. */
if ((len > 0) && (s[0] == '-')) {
first++; m = -1;
}
if (len <= first) return -1;

if (s[first] == '0') {
if (s[first + 1] == 'x') {base = 16; first += 2;}
else if (s[first + 1] == 'b') {base = 2; first += 2;}
}

for (i = first; (s[i] != ' ') && (s[i] != 0) && (i < len); i++);

*o = 0;
i--;
while (i >= first) {
/* ASCII is actually pretty darn clever - if you mask out 0x20,
* it removes caps and maintains the characters we need. */
cc = s[i] & 0xdf;

/* '0'-'9' are 0x30, which are remapped to 0x10 */
if ((cc >= 0x10) && (cc <= 0x19)) {
v = cc - 0x10;
} else if ((cc >= 'A') && (cc <= 'F')) {
v = cc - ('A' - 10);
} else v = 255;

if (v >= base) return -1;
*o += (v * m);
m *= base;

i--;
}

return 0;
}

Tuesday, January 12, 2010

risp language concept...

Too tired to finish this, but this is hopefully going to be a simplified LISP/scheme with functions as objects with implicit continuations. I have a feeling there's profound stuff in here that I'm just too tired to reach, but I don't wanna lose this. Sorry about the incoherence. ;)

Risp Is a Small lisP.

everything is a list
all objects are immutable and reference counted - copy-on-write?
lists can have different cell sizes - 8/16/32/64-bit

functions have one parameter but multiple runtime states. function states are mutable.

for instance - divide:
• first load sets up base
• repeated loads do the divides

(func divide
(local value)
(= value $)
(/ value $)
)

functions don't end unless you say they end - they just automatically break/hold at the end of the list.

func list:

• name
• local variables
• run [1..x]

goto lets you jump between runs. don't know how to label them.

'up' keyword pushes a value into the return list.

(func addall
(local v)
((+ v $) (up v))
)

$ is the single parameter. handling multiple parameters is done via staged/multiple calls, you can set up multiple locals that way easily and do the heavy/repeated lifting with a later state.

(func gimmestuff
(local myaddall addall)
(myaddall 1 2 3 4 5)
(myaddall 6)
)

(def catcher (= gimmestuff)

= (may change) can "catch" up statements and build a new list.

you can have functions that run functions and as long as there's no active catching statement, it's returned to the next parent. if there's no parent that can receive it, it is caught by /dev/null. ;)

my 'data-function identity' - executing (variable) = (func variable (local value) (up value)) in other words a non-function variable pushes itself up when run. therefore everything is executable.

Monday, January 11, 2010

Tonight's hackish code...

... is a 16-bit ppm luminance booster/blower-outer.

To use:

- Convert your image into a 16-bit .ppm file. I use "dcraw -4 -h [file.cr2]" to convert a raw file. Raw DSLR files have enough color depth to do interesting things, even though there *is* a noise floor to contend with still...

- Build https://code.google.com/p/chadslab/source/browse/trunk/hsv2.c with "-O3" and preferably SSE math if you're not on a 64-bit system.

- Then run it as "./a.out 0.8 0.99 < [16-bit.ppm] > [new 16-bit ppm]"

- Finally do "gm convert [new ppm] [out.jpg]" to get a postable .jpg file.

The code is entirely uncommented and doesn't even care if you accidently feed it an 8-bit file, it'll just get very confused. Not recommended. ;)

The main concept is to convert RGB into HSL, play with L, and then you get a brighter output.

Some results are at http://www.flickr.com/photos/happycube

edit: source at http://code.google.com/p/chadslab/source/browse/trunk/hsv2.c

- Chad

Wednesday, January 06, 2010

Some new/random ideas...

A stateful/functional/concurrent programming language? These are very rough notes as I'm getting too tired to write more about it tonight.

const int exampleconstant = 12345;
^ syntatic sugar for:
object exampleconstant {
start() = {int this = 12345; state = const;}
}

class foo {
start(type(input) != foo) = {
int i = 0;
int a = 32;
int b = 64;
state = wait;
}
start(typeof(input) == foo)) {
this = input;
}
iterate(typeof(input) == integer) = {
a = a + input;
b = b - input;
i = i + input;
output = a * b;
state = (a < b) ? iterate : end;
}
iterate(typeof(input) != integer) = {
print("illegal input: " + input);
output = error;
}
end() = {
output = i;
}
}

It's an odd mixture of functional/concurrent programming with a C-like syntax.

What makes it different than you see in the code sample...

- input and output are reserved variables. you don't have to 'catch' the output if it's not the type you're looking for, i think. they can also be arrays.

- state is an implicit variable that denotes what to run on the next trigger. i.e. all objects are state machines.

- functions are transactional. everything you see changed is actually pushed into the object at the end of the iteration - what would be a side effect in a regular language is *not* one here.

- objects can also be an instance of one variable.

----

slightly leaving cloudcucooland, i should write a simple FM-type synthesizer because, well, they're not hard to do.

the synth algo i have in mind supports continuous frequency adjustment (calculus-)integration. the frequency and amplitude are continuous functions in time, allowing for smooth changes in generated sound.

sine waves can be flattened from from triangular (0) to square (1), with sine = 0.5. phase restrictions can create interesting waveform patterns on top of that. for instance sawtooth waves can be generated by using (0, pi/4?) phase restrictions.

---

haven't touched my ARM project lately. need to get interrupts working, add newBSD/MIT license, and give credit to Vijay Kumar for showing the path.

I want something simple to play with registers without flashing - it might mean making the serial code I have now a bootloader that can cut over to a new downloaded program in memory... or I might write something small and FORTHlike.