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;
}

No comments: