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

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> I did have another idea, to keep the existing structure, but also get the code a bit less messy [no setjmp/longjmp!], which is to simply make a main loop that has a statemachine in it, and it does either "run the program" or "enter a line" functionality. That would be a lot less different from the current code.

    That sounds good. How does it work?

    >> I think there are several places where a function could really do with a table (and sometimes a loop, but not always) rather than using a long sequence of if/else or if/return.
    For example, the opcode_to_text() and parse_operator(). I also think compile_line could do with a bit of refactoring into a set of compile_XXX functions and a table.

    I definitely agree there. I do like to avoid in-place initialization of arrays, though, since it's error prone, so I would like to follow the approach used to build the VM's dispatch table. It's a rather convoluted process, I know (eg: the ugly the minibasic::interpreter::initialization_hack), but it allows you to define new constants without having to worry about the order that it's added in.

    >> Anyway, I'd say, don't lump the various bits together under the `mini_basic' class. If you separate the `compiler' from the `interpreter' many types of formal additions to the particulars of the supported dialect could be written without needing to "open" either the `mini_basic' or the `interpreter' class.

    That's kind of what I was thinking when I mentions the heirarchy aspect of it. However we deal with it, though, just keep in mind that, for instance, the INPUT command will need to compile and execute code to pass along to the main VM (so a temporary VM within a VM), so we just need to ensure that more than one VM can be instantiated at once, independant of eachother.

    >> And if you only need one or two supported parameters lists, I'll happily post a simple but independent class to use instead of actually using method pointers directly. I'm thinking particularly of passing the state/compiler/interpreter as a parameter. (That way you could get a little more functionality without relying on Boost or TR1.)

    My only contention there is that another layer could affect the speed of execution. That may be a good candidate for some of the other table-driven mechanisms, however, and at any rate, I'd like to see how it would be implemented.

    >> Also, if you two are really going to work on this a under the GPLv3 license I'll certainly try to help when/where I can lend a hand.

    I'm not really sure what the major differences between GPLv1 and GPLv3 are, but I'm assuming either would be adequate.

    >> Edit: Oh, and as much as I hate implementation macros, that longish series of associations would be one place where I'd suggest them.

    I have a strong distaste for macros, and would rather not use them, if possible. Having said that, I'd be willing to debate their usefulness in this context, however, if you really think they'd help.

    >> Edit: Er... and not that it matters, but my name is Zero Valintine.

    That's a very unique name. I've never seen the use of it before - it it a family name?

    Oh, and matsp - what shall I put yours down as?
    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;
    }

  2. #2
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    "hmm... as in you will only [...] other Free Software/Open Source license?"

    *shrug*

    No, but the only reason we have so many licenses is that no one bothers to understand the existing ones well enough. You really only need GPL, the GPL offspring, and Apache for %99.9 of all projects. What I mean to say is, I'll be more inclined to favor this little project if it is released under the GPL. As for the "v3", that's just a habit; I prefer the GPLv3, but any one would make me happy.

    "That's kind of what I was thinking [...] once, independant of eachother."

    I'm not sure where it would fit in your hierarchy, and I try to avoid bare WIN32, but I was thinking of trying my hand at a simple editor window, cloning the look of the console as much as I could, so we could drop the implicit singleton of the actual console window. I figure a simple panel with a text box and optionally a status bar--for debug/step/trace--would go a long way. Let me know if you think I should follow that a little further.

    "My only contention there [...] it would be implemented."

    True enough, I suppose. I had used it everywhere, but using it only on the compiler side, therefore assuming any expansion could "compile" to your VM, wouldn't be too bad--draining execution of the VM.

    And sure, I'll try to post my approach soon.

    "I have a strong distaste for [...] really think they'd help."

    I'm not sure that would go well for me as I never use implementation macros in my own work. ^_^;

    "That's a very unique name. I've never seen the use of it before - it it a family name?"

    Well, you asked for it: I'm a mutt. I have a lot of family names to choose from from my direct ancestors. (My family tree forks a little too often if you know what I mean, and if you don't... it's best not to discuss it here.) The names I was born with, three other last names from my family, unfortunately associated me with the useless, foolish parasites the make up the 280+ members of my local extended family. I had it changed; I'm using a far older name in my ancestry. So, yea, in a way, it is a family name.

    Soma

    (My full name is "Zero Soma Valintine". You see, I am a big fan of puzzles. To this end, I have a long standing tradition: send me a private message wish the correct interpretation and I'll donate $15 in the name you choose to the charity or open source project of your choice.)

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Sebastiani View Post
    >> I did have another idea, to keep the existing structure, but also get the code a bit less messy [no setjmp/longjmp!], which is to simply make a main loop that has a statemachine in it, and it does either "run the program" or "enter a line" functionality. That would be a lot less different from the current code.

    That sounds good. How does it work?
    If that's your subtle way of saying "Have you proven that it works yet", then the answer is no, I haven't implemented that. I've been busy preparing my sons 5th birthday by spending a lot of money at Toys'R'Us and Game - he's getting a bunch of Star Wars Lego models, and the second Lego Star Wars PS-2 game.
    Oh, and matsp - what shall I put yours down as?
    Mats is my first name, Petersson my last name.

    I think it's fair to also mention the original author of MiniBasic: Sylvain BIZOIRRE - at least as far as "this implementation is based on an assembler variant by ..." or some such.

    As to the Win32, editing etc, perhaps we should abstract that out into a separate class, so that it can be implemented using Win32, Curses or something else. It would make it a bit more portable! Certainly, if we want this to be at least reasonably successful, we should ensure that it can be built for non-windows platforms, even if it's not "complete" in those systems.

    --
    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. #4
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    "As to the Win32, editing etc, perhaps [...] not "complete" in those systems."

    I had been working against a comparatively simple abstraction under the assumption we could glue them together easily enough. I'll post the terminal/console part of the abstraction. Unfortunately, my changes to the interpreter made it unusable in the context of the original and may have been too slow from the considerable use of polymorphic composition.

    I should probably explain that... just in case Sebastiani is headed down that same road. My changes were able to load existing "mini-basic" files easily enough, but the expression simplification and name aliasing stuff left the source far different than what was loaded. It performed the same mechanic, but did not result in the same source. So, if you loaded a file and promptly saved it the result wold be drastically different from the original. Any constant mathematic expressions with important magic numbers, which is obviously all that is available to the original, were compressed to the constant result before being passed to the interpreter or saved. It, basically, mangled the source.

    Anyway, I like the idea of having a dedicated trace/debug area, but I don't want to add to many dependencies either. It's pretty basic to split the terminal area up into multiple windows with `curses' so for now how about we just do that (only with the WIN32API)? For example, if the debug flag is set keep the height 2 lines longer with some arbitrary byte, maybe just `-', separating the status line from the actual buffer area. Will that work for everyone else? Possibly adding a dedicated `???::trace(const std::string)' function/method this purpose?

    I figure you guys can guess what exactly these methods return so I'm not going to label anything for now.

    Soma

    Code:
    typedef uint32_t colour_type;
    typedef std::pair<uint32_t, uint32_t> dimension_type;
    typedef std::pair<colour_type, colour_type> font_type;
    
    class terminal_server // singleton
    {
       public:
          std::pair<bool, font_type> colour
          (
             colour_type new_foreground_colour,
             colour_type new_background_colour
          );
          std::pair<bool, font_type> colour_at
          (
             uint32_t x_offset,
             uint32_t y_offset
          );
          std::pair<bool, bool> echo_mode
          (
             bool with_echo
          );
          std::pair<bool, dimension_type> move
          (
             uint32_t new_x_offset,
             uint32_t new_y_offset
          );
          // modified virtual character code (F5, "Up Arrow", Escape)
          std::pair<bool, uint32_t> read();
          std::pair<bool, dimension_type> resize
          (
             uint32_t new_width,
             uint32_t new_height
          );
          std::pair<bool, std::string> text
          (
             const std::string & new_text
          );
          std::pair<bool, std::string> text_at
          (
             uint32_t x_offset,
             uint32_t y_offset
          );
          std::pair<bool, std::string> title
          (
             const std::string & new_title
          );
       public:
       private:
          ???::any_like
       private:
    };
    
    class line_editor // implied singleton
    {
       public:
          // ??? (glue)
          std::pair<bool, std::string> read_some();
       public:
       private:
          terminal_server terminal;
          ubasic_interpreter interpreter;
       private:
    };

  5. #5
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    OK, so before everyonce gets started writing more code, let me just post a final revision so that there won't be any duplication of effort. We can break everything down into modules and work on them individually.

    >> As to the Win32, editing etc, perhaps we should abstract that out into a separate class, so that it can be implemented using Win32, Curses or something else.

    That's an excellent idea. I'm all for that.

    >> I was thinking of trying my hand at a simple editor window, cloning the look of the console as much as I could, so we could drop the implicit singleton of the actual console window.

    Sounds fine to me. The only thing that worries me is that having to work with things on the pixel level might get complicated. For example, since there is no standard guaranteed way to get a monospaced font in a GUI, you might have to just store the glyphs as bitmap images. I don't know. If you feel up to it, go for it. But just for posterity, I'll post the (possibly) IO code I have, as a short term alternative.

    >> If that's your subtle way of saying "Have you proven that it works yet", then the answer is no, I haven't implemented that. I've been busy preparing my sons 5th birthday by spending a lot of money at Toys'R'Us and Game - he's getting a bunch of Star Wars Lego models, and the second Lego Star Wars PS-2 game.

    And so the legacy of Star Wars is passed down to the next generation. Very good. Anyway, no rush, and Happy Birthday to your son.

    >> Well, you asked for it...

    Indeed. Well, don't feel bad. I have my share of "foolish parasite" family members; a notorious example being my (not-so-)great uncle, Billie Sol Estes. His actions and behavior caused a so much grief and shame for our family (mostly the older generation, anyway) that it got to the point where many complained that there was almost a stigma attached to the name itself!

    >> I think it's fair to also mention the original author of MiniBasic: Sylvain BIZOIRRE

    OK, I've updated the credits. One last question, though: should I include the original MiniBasic creator (I think he has a Japanese name - I'll look it up)?

    [edit]
    Soma, I posted without seeing if there were any previous - I'm reading through your last post now, though...
    [/edit]
    Last edited by Sebastiani; 04-11-2009 at 09:04 PM.
    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. #6
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    "OK, I've updated the credits. One last question, though: should I include the original MiniBasic creator (I think he has a Japanese name - I'll look it up)?"

    Well, as far as I am concerned, you may give credit to all you wish. That said, the original assembler we are working from was an just an assembler project based on a "how to" document project implementing this dialect which is based on an old BASIC distribution for small machines which is itself based on a distribution for the old Apple computers. My point is, where exactly would you stop?

    (This is what I found out when I tried to find a better existing implementation to work from than the horribly confusing assembler you guys translated.)

    Edit: And of course, this is the age of the "wiki-people"; there is no telling how wrong the information I found may be...

    Soma

  7. #7
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Soma, the design looks good. Let me know if you want me to post the IO code I have (for reference, if nothing else).
    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. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by phantomotap
    No, but the only reason we have so many licenses is that no one bothers to understand the existing ones well enough. You really only need GPL, the GPL offspring, and Apache for %99.9 of all projects.
    It is not so simple, considering that lawyers disagree on how the various licenses would be interpreted in a court of law in various jurisdictions. Personally, I would choose OSL and AFL over the LGPL and Apache license respectively as I am convinced by Lawrence Rosen's arguments, but the FSF has been sprouting license FUD against those two licenses for some time now.

    Quote Originally Posted by phantomotap
    What I mean to say is, I'll be more inclined to favor this little project if it is released under the GPL. As for the "v3", that's just a habit; I prefer the GPLv3, but any one would make me happy.
    Right

    Quote Originally Posted by Sebastiani
    OK, so before everyonce gets started writing more code, let me just post a final revision so that there won't be any duplication of effort. We can break everything down into modules and work on them individually.
    I think that using the appropriate tools is even more important now, e.g., automated merging of the different parts so that you can more readily integrate them instead of merging them by hand.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Alright, well here's the IO code. It's truly a mess, but I'm pretty sure that it works (well, mostly anyway ).

    >> I think that using the appropriate tools is even more important now, e.g., automated merging of the different parts so that you can more readily integrate them instead of merging them by hand.

    I'm divided. On the one hand, that seems like a great idea, on the other, it does just add yet another complication...
    Last edited by Sebastiani; 04-12-2009 at 03:17 AM.
    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. #10
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    "It is not so simple, considering [...] licenses for some time now."

    Edit: Congratulations must be offered to the few who had time to read my eight page thesis. Now I offer only this: "FUD" is the crime you commit when you choose to infer the machinations of one party in support of another. We need real victories or real defeat; we will celebrate of learn as appropriate. To this end, we need to eliminate most of the countless software licenses so we can develop a history from which we may succeed or fail.

    [Edit]
    "Alright, well here's the IO code."

    I'll take a look at it in a few moments. My stomachache demands my full and undivided attention... now if only I could say that about my girlfriend. ;_;
    [/Edit]

    Soma

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Ok, I'm supposed to be at a Easter Dinner at mother-in-law's in a bout 1 minute... But I'm sure they don't mind me being a little bit late. I haven't had any time to

    I think Laserlight makes a good point on the "merging source" situation.

    So has anyone else have experience with Mercurial?
    Mercurial - Mercurial

    It works on multiple platforms - which is a good thing.

    It is distributed and allows us all to have our own copy, and submit changes to the master code line as we see fit.

    I'm sure CVS and GIT does the same thing, and several others.

    So if we choose mercurial, would anyone else object very much?
    If we wanted to use mercurial, our project could live on Mercurial hosting &mdash; bitbucket.org

    I picked mercurial because I have used it before, and bitbucket because it came up first in google...

    Any constructive advice welcome.

    --
    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.

  12. #12
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    "I think Laserlight makes a good point on the "merging source" situation."

    You remember a few pages back when I said "I have something I want to discuss with you two."? I wanted to discuss these very things--the license, VCS, and server.

    "So has anyone else have experience with Mercurial?"

    I have no experience with Mercurial, but I've heard enough about it that I've read the tutorial and contemplated a toy repository. So, yea, Mercurial gets my vote.

    "It is distributed and allows [...] to the master code line as we see fit."

    And according to what I've heard, you can arbitrarily create forks for attempting major revisions and automatically merge these changes to root or toss them as appropriate. This makes me salivate... it makes me tingle. ^_^;

    As for the server, I've never had anything to do with BitBucket so I can't say anything about them. I've helped with projects on BerliOS and they were great. I've hosted projects on SourceForge, but I can't recommend it. I'd say BerliOS gets my vote, but I'm fine with anything free!

    The GPLv3 is obviously my license of choice.

    "So if we choose mercurial, would anyone else object very much?"

    I don't see why they should. Many, maybe even all, of the open source project servers I've seen with Mercurial support have either nightly snapshots, generative snapshots on demand, or some combination of the two.

    Or was this just targeted at me and Sebastiani?! O_o

    "I'm sure CVS and GIT does the same thing, and several others."

    Unless the modern CVS has greatly improved it isn't half what Mercurial is... I don't want to offend anyone, but I flat out refuse to use CVS. I'll still help. I'll post source at the project forum/list or something.

    Edit: And I hate to bring this up, I truly do, but what about the build system? Apparently one of you, or the other, has MSVC installed which targets Windows nicely, but what about other platforms? (I have the compiler from 2005 installed, but not the IDE and companions.) I like the "autotools" build system almost as much as I like being kicked in the crotch.

    Soma

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by matsp
    It works on multiple platforms - which is a good thing.

    It is distributed and allows us all to have our own copy, and submit changes to the master code line as we see fit.

    I'm sure CVS and GIT does the same thing, and several others.
    CVS is not distributed, and Git's Windows support is still relatively weak.

    Quote Originally Posted by matsp
    If we wanted to use mercurial, our project could live on Mercurial hosting &mdash; bitbucket.org

    I picked mercurial because I have used it before, and bitbucket because it came up first in google...
    Naturally, I would suggest Bazaar and Launchpad instead, but nah, Mercurial and Bitbucket should be fine for your purposes.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #14
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    "Naturally, I would suggest Bazaar and Launchpad instead, but nah, Mercurial and Bitbucket should be fine for your purposes."

    Shut Up! I'm excited to try Mercurial; don't stick your nose where I don't want it!

    Anyway, more seriously, I've been playing with the `terminal' interface and Windows implementation.

    Now, as I've imagined it, I'm having a problem with the echo stuff. I can't manage it in context without employing threads and locking. As it is, this part is or will be a huge time sink. So, I have made a few changes to the way the `terminal' abstraction handles a few things.

    To this end I'm altering the interface I posted dramatically. Currently it uses a `std::uint32_t' for both the foreground and the background. (Which I was intending to use as a full RGBA component.) I'm now proposing we [S]steal[/S] borrow the implementation mechanic from most of the decent text editors. I figure, just use a `std::uint8_t' and associate that value with the particulars of the font, both the foreground and the background, behind the abstraction for whatever the library particulars may demand. (This is similar to what Windows does internally for the console.) Believe it or not, this gave a rather large performance boost. (Granted, anything dropping a WIN32API "mutex" would probably be an improvement.)

    Fortunately, the IO code posted by Sebastiani introduced me to an API I have never considered. I think I'll be able to simplify the implementation a bit more and further improve the abstraction so that anything built on top of the abstraction can more easily implement the line editor stuff we need.

    Also, I think I've nailed the last of the startup/cleanup code needed for the console window. You can change the size, the title, dump random text to the screen, and the cleanup restores everything to exactly what it was before it was started without polluting the memory with unused structures. I'm not positive, and I'm not sure why I had so much trouble with this, but I thing I've got it. Regarding this, I'd say, on exit, after we restore everything, we dump the license, copyright, the version, notices, and maybe a "thank you" or something to `std::cout' leaving some indication of what has transpired in the window--assuming we aren't responsible for destroying the window.

    I have some notes I'd like to ask you about your VM Sebastiani, but I've finally gotten tired enough I thing maybe I will not have nightmares... I'll post when I wake up.

    Soma

  15. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by laserlight View Post
    Naturally, I would suggest Bazaar and Launchpad instead, but
    nah, Mercurial and Bitbucket should be fine for your purposes.
    Of course, you WOULD say that. Do you have shares in Bazaar or something?

    I take that as an approval of the idea!

    I will try to set something up in the next couple of days.

    --
    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.

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