Thanks for trying this out with ebasic. I don't know why the segmentation fault is happening; does it happen with the most recent github code? I can't quite reproduce it here: the ebasic3.zip file you posted doesn't have the header files, and when I replaced them with the ones from the old ebasic.zip file I got a bunch of other errors.
Thanks for trying this out with ebasic. I don't know why the segmentation fault is happening; does it happen with the most recent github code? I can't quite reproduce it here: the ebasic3.zip file you posted doesn't have the header files, and when I replaced them with the ones from the old ebasic.zip file I got a bunch of other errors.
Sorry about the missing header files. Here is a complete set of sources. I don't see the segmentation fault anymore because of the internal error messages I mentioned in another post.
Eric: I see you've fixed a number of the problems I reported. I'm now able to compile most of my program but I'm having trouble with a new file I added that implements vsnprintf. I get an error in an invocation of va_arg. Is that implemented yet? I've attached the revised sources to this message. The error I get is:
/Users/dbetz/work/ebasic3/simple_vsnprintf.c(140) error: incompatible types in assignment
Thanks David. I have got some code in to implement va_args, but it's only very lightly tested so you've probably found a bug . I'll take a look.
Thanks for looking into this. In the meantime, I've been trying to make a reference version that runs on the PC and am having some trouble because PCs now seem to default to 64 bit mode where a pointer and an int are not the same size. This causes problems for the current version of ebasic3 because it thinks it can cast a pointer to a function to a VMVALUE type and back again. That probably wasn't a good idea to begin with but it's now causing the PC version to fail. I'm going to fix that but it may take a while.
I got ebasic3 running on the Mac by compiling it to use 64 bit values. Here is a simple example:
100 for x=1 to 10
110 print x, x*x
120 next x
run
1 1
2 4
3 9
4 16
5 25
6 36
7 49
8 64
9 81
10 100
OK
So it seems that the code works. I wanted to verify that before actually trying to run the fastspin executables so I have a known baseline. FYI, the language itself doesn't need or use line numbers. They are just required by the dumb line editor.
In the meantime, I've been trying to make a reference version that runs on the PC and am having some trouble because PCs now seem to default to 64 bit mode where a pointer and an int are not the same size. This causes problems for the current version of ebasic3 because it thinks it can cast a pointer to a function to a VMVALUE type and back again.
Could you use "intptr_t" for VMVALUE? That's supposed to be an integer type that will hold any pointer.
In the meantime, I've been trying to make a reference version that runs on the PC and am having some trouble because PCs now seem to default to 64 bit mode where a pointer and an int are not the same size. This causes problems for the current version of ebasic3 because it thinks it can cast a pointer to a function to a VMVALUE type and back again.
Could you use "intptr_t" for VMVALUE? That's supposed to be an integer type that will hold any pointer.
Is it signed? I suppose it probably is since it's not called "uintptr_t".
I've fixed the va_args bug, and a few other things that came up after it. Now it's running into another static variable problem (not sure what's going on there but some assembler symbols are undefined) and also a problem with comparing against function pointers. That's going to take a bit of thinking about: function pointers in fastspin are a lot more complicated than in GCC, because they can point to closures. That shouldn't happen in C, but it's still getting the compiler mixed up, and actually points to a bug of sorts even in BASIC, where this code:
function foo()
return 1
end function
function check( a as any, b as any )
return a=b
end function
print check(@foo, @foo)
prints 0, because each of the "@foo" operations to take the address of foo builds a dynamic method pointer. This needs some work to get correct for C, where we would definitely want the similar comparison of &foo and &foo to return 1.
Incidentally, your sample ebasic BASIC code compiles and runs as-is under fastspin . I think the ebasic syntax is mostly compatible with freebasic, although there will probably be a few things that would need tweaking for some programs. Still, it would be neat to be able to do interactive development with ebasic and then optionally compile to a faster form later with fastspin.
Incidentally, your sample ebasic BASIC code compiles and runs as-is under fastspin . I think the ebasic syntax is mostly compatible with freebasic, although there will probably be a few things that would need tweaking for some programs. Still, it would be neat to be able to do interactive development with ebasic and then optionally compile to a faster form later with fastspin.
I'm not sure what BASIC "standard" I used when designing ebasic. To be honest, I don't really like any of them. In any case, I'm pretty sure it wasn't freebasic because I didn't know about that at the time. Is it like Microsoft BASIC? What I really hated was "wend" to end "while" loops.
I noticed a spin2cpp update and tried compiling ebasic3 again. I got further this time but now I have an odd error where symbols that are defined in a file are flagged as undefined in that same file. If I take away the "static" qualifiers then the undefined error goes away but then I get some odd errors later. With the "static" declarations in place I get this error:
/Users/dbetz/work/ebasic3/db_compiler.c(174) error: Unknown symbol bi_waitcnt
/Users/dbetz/work/ebasic3/db_compiler.c(175) error: Unknown symbol bi_waitpeq
/Users/dbetz/work/ebasic3/db_compiler.c(176) error: Unknown symbol bi_waitpne
If I comment out the "static" qualifiers on the three lines that define those symbols I get these errors:
ebasic3.p2asm(11618) error: Unknown symbol __static__0002
ebasic3.p2asm(11618) error: Unknown symbol __static__0002
ebasic3.p2asm(11620) error: Unknown symbol __static__0009
ebasic3.p2asm(11620) error: Unknown symbol __static__0009
ebasic3.p2asm(11622) error: Unknown symbol __static__0010
ebasic3.p2asm(11622) error: Unknown symbol __static__0010
Yes, the way fastspin currently handles static variables and functions is fundamentally broken. I'm in the process of re-writing it, but it will take a while. Sorry!
Yes, the way fastspin currently handles static variables and functions is fundamentally broken. I'm in the process of re-writing it, but it will take a while. Sorry!
Okay, no problem. Let me know when you have something new I can try. Thanks!
I've re-written the fastspin C handling of "static", and it compiles ebasic3 now. It doesn't seem to work right, but I still have an older ebasic3 (e.g. VM_getline is stubbed out). I hope to try it on a more recent ebasic3 later.
I've re-written the fastspin C handling of "static", and it compiles ebasic3 now. It doesn't seem to work right, but I still have an older ebasic3 (e.g. VM_getline is stubbed out). I hope to try it on a more recent ebasic3 later.
Alas, it runs into another problem: global initializers like:
char *bufend = buffer + BUFSIZE;
are not compiled properly, although:
char *bufend = &buffer[0] + BUFSIZE;
are. The implicit conversion of "buffer" to "&buffer[0]" only happens inside functions, not at file scope. I need to think about how to fix this, it may take me a little while to come up with a good solution.
Alas, it runs into another problem: global initializers like:
char *bufend = buffer + BUFSIZE;
are not compiled properly, although:
char *bufend = &buffer[0] + BUFSIZE;
are. The implicit conversion of "buffer" to "&buffer[0]" only happens inside functions, not at file scope. I need to think about how to fix this, it may take me a little while to come up with a good solution.
If that's the only instance of that I'll change it in my code. I'm surprised I didn't have that in some init function anyway. I should probably fix that problem.
I just pushed some minor updates that let ebasic3 build with fastspin. I made the change you suggested in your message above but the program still doesn't work. How does your getchar() implementation work? Does it do any buffering? I'm assuming it just returns the next character that the user types as if you were in raw mode under Unix. Is that what it does? If not, is there a lower level function that just gets the next character?
Just as a sanity check I compiled ebasic3 with PropGCC and it seems to work:
Davids-Mac-mini:ebasic3 dbetz$ propeller-load -b c3 ebasic.elf -r -t
Propeller Version 1 on /dev/cu.usbserial-A8004ILf
Loading the serial helper to hub memory
9808 bytes sent
Verifying RAM ... OK
Loading external memory driver 'c3_xmem.dat'
968 bytes sent
Loading program image to flash
45172 bytes sent
Loading .xmmkernel
1984 bytes sent
[ Entering terminal mode. Type ESC or Control-C to exit. ]
ebasic3
10 for x=1 to 10
20 print x, x*x
30 next x
run
1 1
2 4
3 9
4 16
5 25
6 36
7 49
8 64
9 81
10 100
OK
list
10 for x=1 to 10
20 print x, x*x
30 next x
OK
I just pushed some minor updates that let ebasic3 build with fastspin. I made the change you suggested in your message above but the program still doesn't work. How does your getchar() implementation work? Does it do any buffering? I'm assuming it just returns the next character that the user types as if you were in raw mode under Unix. Is that what it does? If not, is there a lower level function that just gets the next character?
getchar() is just a raw bitbanged input, no buffering, and raw mode.
Not sure what's wrong now, but there are still plenty of bugs in fastspin I think. I won't have much time today, but I'll try to take a look at it later.
I just pushed some minor updates that let ebasic3 build with fastspin. I made the change you suggested in your message above but the program still doesn't work. How does your getchar() implementation work? Does it do any buffering? I'm assuming it just returns the next character that the user types as if you were in raw mode under Unix. Is that what it does? If not, is there a lower level function that just gets the next character?
getchar() is just a raw bitbanged input, no buffering, and raw mode.
Not sure what's wrong now, but there are still plenty of bugs in fastspin I think. I won't have much time today, but I'll try to take a look at it later.
Thanks!
Eric
Raw input is perfect. Thanks.
I'll look at ebasic3 more in the coming days to try to figure out where it is going wrong. It gets further with p2gcc but it also has trouble there as well. I guess the first thing to get working is the editor and command parser so I can type in a program and "list" it.
I'll look at ebasic3 more in the coming days to try to figure out where it is going wrong. It gets further with p2gcc but it also has trouble there as well. I guess the first thing to get working is the editor and command parser so I can type in a program and "list" it.
If you do get a chance to look at it that'd be great -- please let me know what bugs you find!
An easy way to debug a fastspin compiled program is to sprinkle "__builtin_printf" statements through it. __builtin_printf doesn't need any header files or declarations, and works just like printf.
Eric: Is it possible that local static arrays are not working? This function prints the correct value for token but that value doesn't seem to be returned correctly.
static char *NextToken(System *sys)
{
static char token[MAXTOKEN];
int ch, i;
/* skip leading spaces */
while ((ch = *sys->linePtr) != '\0' && isspace(ch))
++sys->linePtr;
/* collect a token until the next non-space */
for (i = 0; (ch = *sys->linePtr) != '\0' && !isspace(ch); ++sys->linePtr)
if (i < sizeof(token) - 1)
token[i++] = ch;
token[i] = '\0';
__builtin_printf("Token: '%s', Remainder: %s\n", token, sys->linePtr);
return token[0] == '\0' ? NULL : token;
}
Actually, it is not the static array that is the problem. It seems to be the return statement. If I change it to this it works.
return token[0] == '\0' ? NULL : &token[0];
Thanks. That's fixed in the current github. Now ebasic is running into some kind of problem inside VM_printf. I think it may be a bug in the varargs handling; I've already found (and fixed) one issue, but there must be something else because my bug fix didn't change anything in ebasic's behavior .
Comments
Thanks for the sample!
Could you use "intptr_t" for VMVALUE? That's supposed to be an integer type that will hold any pointer.
getchar() is just a raw bitbanged input, no buffering, and raw mode.
Not sure what's wrong now, but there are still plenty of bugs in fastspin I think. I won't have much time today, but I'll try to take a look at it later.
Thanks!
Eric
I'll look at ebasic3 more in the coming days to try to figure out where it is going wrong. It gets further with p2gcc but it also has trouble there as well. I guess the first thing to get working is the editor and command parser so I can type in a program and "list" it.
If you do get a chance to look at it that'd be great -- please let me know what bugs you find!
An easy way to debug a fastspin compiled program is to sprinkle "__builtin_printf" statements through it. __builtin_printf doesn't need any header files or declarations, and works just like printf.
Thanks,
Eric
Thanks. That's fixed in the current github. Now ebasic is running into some kind of problem inside VM_printf. I think it may be a bug in the varargs handling; I've already found (and fixed) one issue, but there must be something else because my bug fix didn't change anything in ebasic's behavior .