fastspin C compiler

245

Comments

  • 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.
  • David BetzDavid Betz Posts: 13,480
    edited 2019-02-16 - 20:49:31
    ersmith wrote: »
    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.
  • Hmm, looks like something very weird is going on in the function parsing code. I'll try to figure it out.

    Thanks for the sample!

  • ersmith wrote: »
    Hmm, looks like something very weird is going on in the function parsing code. I'll try to figure it out.

    Thanks for the sample!
    Thanks for looking into this!

  • 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.
  • ersmith wrote: »
    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.

  • David BetzDavid Betz Posts: 13,480
    edited 2019-02-17 - 20:37:29
    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.
  • David Betz wrote: »
    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.

  • ersmith wrote: »
    David Betz wrote: »
    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.
  • ersmith wrote: »
    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
    
    Again, the code is attached.
  • Also, I still have some code commented out in db_edit.c:
    /*static*/ struct {
        char *name;
        void (*handler)(System *sys);
    } cmds[] = {
    {   "NEW",      DoNew   },
    #ifdef LOAD_SAVE
    {   "LOAD",     DoLoad  },
    {   "SAVE",     DoSave  },
    {   "CAT",      DoCat   },
    #endif
    {   "LIST",     DoList  },
    {   NULL,       NULL    }
    };
    
    If I include the "static" qualifier here I get these errors:
    /Users/dbetz/work/ebasic3/db_edit.c(68) error: Method reference on non-class expression
    /Users/dbetz/work/ebasic3/db_edit.c(69) error: Method reference on non-class expression
    /Users/dbetz/work/ebasic3/db_edit.c(71) error: Method reference on non-class expression
    /Users/dbetz/work/ebasic3/db_edit.c(72) error: Method reference on non-class expression
    
  • 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!
  • ersmith wrote: »
    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.
  • ersmith wrote: »
    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.
    Cool! I'll try it later tonight. Thanks!
  • 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.
  • ersmith wrote: »
    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.

  • Eric: I just updated and WOW! You certainly changed a lot in this update. Thanks!
  • 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
    
  • David Betz wrote: »
    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
  • ersmith wrote: »
    David Betz wrote: »
    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.

  • David Betz wrote: »
    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
  • 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];
    
  • David Betz wrote: »
    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 :(.
Sign In or Register to comment.