Thread: Converting MINI-BASIC in MASM over to C++?

  1. #211
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Well, it seems like the repository is working, at least.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  2. #212
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Yep. Thanks for setting that up, by the way.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  3. #213
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Sebastiani View Post
    Yep. Thanks for setting that up, by the way.
    No problem. If I ever start another project like this, I'd do that from day 1 or 2, as it wasn't hard at all, and cost nothing.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #214
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I've just fixed a few minor things and added a "todo.txt" in the root directory.

    Edit: And some more updates - I've tried to make pitman run, which it does to some extent, but nowhere near all the way.

    --
    Mats
    Last edited by matsp; 04-16-2009 at 06:23 PM.
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #215
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Well, I've got pitman "running" - although it just doesn't display correctly. Almost everything else is implemented - I just can't believe how difficult it has been trying to implement simple console IO. Maybe it *would* be easier to implement using GUI code? What a pain in the arse. Anyway, I'll keep working on other things until I have a chance to talk to you guys about this.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  6. #216
    Registered User
    Join Date
    Jun 2004
    Posts
    76
    Looking good. Anxious to see the next update.

    Paul

  7. #217
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    I've put more of the experimental code into the repository. It still needs work, but it's fairly functional. The main issue right now is I/O (of course).
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  8. #218
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Try to be more careful Sebastiani. You reverted some of Mats updates. I've pushed a new set to properly merge your changes and his from an older version.

    (I don't know the Mercurial way to fix the problem. I just reverted to an old version, pulled your changes, and then merged his changes. I imagine that there is an appropriate Mercurial way to do this, but I wanted to get it fixed so I can examine all the changes at the same time. If anyone knows the Mercurial way to fix these sorts of problems, please let me know.)

    I'm working now on merging back my source layout changes, but I probably will not push another set until I get the updates to the terminal interface Sebastiani and Mats obviously needs. (I've already examined some of the changes. The terminal interface is woefully inadequate. I'm free for the rest of the day so I hope to have it done by tomorrow.)

    Sebastiani (Notes):

    I tossed what work I did on the GUI front. (I find the WIN32API absolutely horrible.) That said, I am working on the terminal/console stuff and will probably continue working on it until I have the new primitives added later today--I hope.

    Aliasing the pointer to determine endianness doesn't work everywhere. We might just want to use a simple macro or expansion chosen from a `config.h' file.

    I'm going to lift your "singletonizer" for the terminal interface and the various types depending on it, but I'd rather throw a class derived from `std::runtime_error' tagged with the type information (eg. "throw multiple_instantiation<singleton<terminal_controll er>>()"). Does that work for you?

    As for your "VM", what would you say to having an "emitter" class for your compiler and and a "handler" for your interpreter? It wouldn't slow the normally provided mechanisms down, but it would allow for expansion nicely. It wouldn't be to difficult to watch for the instruction `interrupt', added to the instruction enumeration, and look the handler routine up with a `std::map'. Granted, it has problems related association, but I was thinking of using a GUID or something to flag a particular function name as being provided. (I have a few cursory notes for a file format allowing for this distinction if you would like to hear them.)

    Mats (Notes):

    *sigh*

    I had some stuff I wanted to talk to you about... but I can't find where I stuck the bloody file! (It isn't in the source tree with my other notes.) Anyway, considering the above merge problems... could you double check that the set I pushed has all of your work? (For my merge I went back to c11 and stepped forward from there; if you've made no new changes we are good.)

    Soma
    Last edited by phantomotap; 04-17-2009 at 06:49 PM.

  9. #219
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Whoops, I think I did it again. =/

    I'm doing something wrong here. Basically what's happening is that when I 'hg push' I get an error, so I do 'hg push -f', not realizing that I'm screwing the current snapshot.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  10. #220
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> I tossed what work I did on the GUI front. (I find the WIN32API absolutely horrible.) That said, I am working on the terminal/console stuff and will probably continue working on it until I have the new primitives added later today--I hope.

    OK, yeah, this I/O stuff has been a real headache.

    >> Aliasing the pointer to determine endianness doesn't work everywhere. We might just want to use a simple macro or expansion chosen from a `config.h' file.

    Is there is some other way then to dynamically detect endianess? I would rather not use a macro, if at all possible.

    >> I'd rather throw a class derived from `std::runtime_error' tagged with the type information (eg. "throw multiple_instantiation<singleton<terminal_controll er>>()"). Does that work for you?

    Sure, that sounds like a good idea.

    >> As for your "VM", what would you say to having an "emitter" class for your compiler and and a "handler" for your interpreter?

    Well, what you describe is essentially the functionality they already provide. But maybe you can give me an example of how that would work so that I can see it more clearly?

    >> It wouldn't be to difficult to watch for the instruction `interrupt', added to the instruction enumeration, and look the handler routine up with a `std::map'. Granted, it has problems related association, but I was thinking of using a GUID or something to flag a particular function name as being provided.

    Do you mean to detect user intervention, or something else?

    >> (I have a few cursory notes for a file format allowing for this distinction if you would like to hear them.)

    Sure. The current binary layout is:
    [signature]
    [major version]
    [minor version]
    [size of line-number lookup table]
    [offset of line-number lookup table]
    [count of strings in string table]
    [offset of string table]
    [code]
    [line-number lookup table]
    [string table]

    Additions/changes are welcome, though.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  11. #221
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Just wanted to add that though I've updated some of the code, I won't be posting any more updates to the repo until we've figured out what I'm doing wrong.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  12. #222
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    I think it has to do with the truncated directory name problem I had earlier. I'll go ahead and try to push the new changes, but I won't force it...
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  13. #223
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    "Is there is some other way then to dynamically detect endianess? I would rather not use a macro, if at all possible."

    *shrug*

    One non-portable solution is as good as any other. At any rate, if you consistently use the swapping/independence routines you've provided I can patch the `config.h' and your implementation later to determine host endianness from a macro falling back on the aliasing if it isn't set.

    "Well, what you describe is essentially the functionality they already provide."

    Yes. You've implemented something very similar for the provided routines of the compiler and codes of the virtual machine. What I'm suggesting is hooks for outside influence to be applied before failure--the handler triggered for unknown functions. (I don't like the idea of having to crack open the implementation to add something simple.)

    "But maybe you can give me an example of how that would work so that I can see it more clearly?"

    *shrug*

    As I ask people I work for: how would you like it to work? My first thoughts provided something reasonably simple.

    Code:
    void alert_emitter(compiler & c)
    {
       // ???
       c.emit_interrupt_header(MAGIC_NUMBER);
       // ???
       c.emit(/*???*/);
       // ???
       c.emit_interrupt_cleanup(MAGIC_NUMBER);
       // ???
    }
    Code:
    void alert_handler(interpreter & c)
    {
       // ???
       int i = pop();
       // i haven't examined the source in
       // enough detail to know how you
       // are handling string data I
       // just assume you have primitives
       // available to track compiled strings
       std::pair<bool, std::string> value;
       value = c.string_from_resource(i);
       if(value.first)
       {
          messagebox("alert", value.second);
       }
       // ???
    }
    Code:
    // from compiler `compile_line'
    // after "else if( skip( "PRINT" ) || skip( "?" ) )"
    // ???
    if(valid_entity(text) && emit_fun = find(emitter.begin(), emitter.end(), entity_name(text))
    {
       // ???
       (*emit_fun)(*this);
       // ???
    }
    // ???
    Code:
    // from interpreter `initialize_table'
       table[ minibasic::INTERRUPT ] = &interpreter::INTERRUPT;
    // from &interpreter::INTERRUPT
       int handler_entity = pop();
       if(handler_fun = find(handler.begin(), handler.end(), handler_entity))
       {
          // ???
          handler_fun(*this);
          // ???
       }
    "Do you mean to detect user intervention, or something else?"

    Actually, I was referring to the possibility of a particular build not providing a particular function. I was talking about a "future proof" file format so additions/expansions could be flagged in a new file format that old versions could still read... if only to explain what was missing.

    "Additions/changes are welcome, though."

    I'll have to post my notes later. I haven't transcribed them from my currently soggy brain. (As I've already said, I do so very hate the WIN32API.) At the very least, beyond the above referenced additions/expansions flags, I would also add a endianness flag--to support native loading for the interpreter--and an area for baked `peek'/`poke' area. (I'm not entirely sure this is necessary. I've never really examined the original assembler. It does allow for some clever tricks if the "line editor" portion works as I think it does in the original.)

    "Just wanted to add that though I've updated some of the code, I won't be posting any more updates to the repo until we've figured out what I'm doing wrong."

    You've done some weird things to the source.

    Try the following steps and let me know if any additional changes will push to the hosted repository without problems or errors. (You should backup your local repository.)

    There is no problem to be honest. I wasn't wrong really, but I wasn't right either. All three of us were working from different "heads". You just need to merge them together before you push another set for the default snapshot to show the latest source from everyone. This isn't strictly necessary yet since we don't have a true "release". In other words, you can safely continue working from your repository--and its "head"--and Mats his repository--and its "head"--pushing the sets back as you make changes. You can merge the heads with remarkable ease. (Use "hg head" to list the various "heads" associated with the current repository.) Actually, what I've show below is probably not even the best way, but after a few tests I'm almost positive it works--regardless of what other approaches may be available. It is significantly faster and easier than what I did the first time around.

    1): hg pull https://[email protected]/matsp/minibasic/ -r 14
    2): hg merge -r 12
    3): hg commit -u sebastiani -m "merging heads 12 & 16"
    4): hg merge -r 14
    5): hg commit -u sebastiani -m "merging heads 14 & 17"

    When you are done "hg head" should list one "changeset"--marked 18--with two parents.

    "I think it has to do with the truncated directory name problem I had earlier."

    I don't think so, but that has caused an odd problem in that grabbing a fresh copy shows both "experimental" directories. You should definitely delete that "MINIBA~1" folder before you commit another change.

    Soma

  14. #224
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    (I'm not editing my post because I'm afraid "cboard" will somehow lose my post as it has in the past.)

    I'll take a moment to explain what I mean by "baked" area.

    I think the original "line editor" portion allows you to directly input commands which affect whatever program is currently loaded--whatever program is executed by "RUN".

    Well, you could, presumably, build a few structures in advance--to save execution time once the interpreter/application is actually running--by loading and saving the "freeplay" independently of the program source. (Later associating the relevant image with a particular source.)

    Soma

  15. #225
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Example, please.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Converting textBox1->Text into a basic string.
    By azjherben in forum C++ Programming
    Replies: 5
    Last Post: 06-07-2009, 08:27 PM
  2. [ANN] New script engine (Basic sintax)
    By MKTMK in forum C++ Programming
    Replies: 1
    Last Post: 11-01-2005, 10:28 AM
  3. what are your thoughts on visual basic?
    By orion- in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 09-22-2005, 04:28 AM
  4. VC++ 6 & MASM (eek)
    By cboard_member in forum C++ Programming
    Replies: 2
    Last Post: 07-16-2005, 10:00 AM