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

  1. #166
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    matsp, have you considered licensing your code under an open source license, and hosting it from some public code repository like Sourceforge? (These days I tend to use Launchpad due to its server side support for Bazaar.) That way Paul Panks and others can just download the updated bleeding edge code immediately instead of pinging you for an update report
    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

  2. #167
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    It's a good idea. I just find that I have just barely time to do the work on the code in the evenings. So I just spend 2 more minutes zipping it up and posting it here.

    But maybe if I get some time over easter, I may well do that.

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

  3. #168
    Registered User
    Join Date
    Jun 2004
    Posts
    76
    That sounds better than constantly asking for updates.

    Paul

  4. #169
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Sorry about the haitus - I had some personal things come up (let's just say I'm an uncle now, twice over ).

    Well, after running a few programs through the interpreter, it became clear that there were still some major bugs to be dealt with. Besides that, the whole design just seems fundamentally flawed to me. So, I would like to make a (difficult) proposition: rewrite the whole thing from scratch. Now, I know that may sound like a big step, but in reality it would probably simplify things since we would be able to implement things as they should; not simply trying to fit a square into a round peg, so to speak. I've done some preliminary prototyping on a virtual-machine driven design and it looks very promising - it would likely be a much more stable, streamlined, and efficient approach altogether, and the design would be more straightforward than what we're currently working with, so I'm pretty sure that it wouldn't take very long at all to produce a fairly functional framework. Furthermore, I would be more than willing to port everything that has been done thus far, so as to minimize the overall affect on the project's progress. Think it over, and let me know how you guys feel about going in that direction.
    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;
    }

  5. #170
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Congratulations to becoming an uncle (again, or was it twins?)

    The design follows the original assembler code, and I think I did say early on that it was a bit rubbish (or something along those lines).

    So if you fancy posting what you are working on right now, just as a reference, I'd be happy to review it.

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

  6. #171
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Twins, thank you.

    I'd be happy to post what I have so far, but mind you it is not at all coupled with the standard minibasic IO yet (using cin/cout to simplify preliminary tests), it's lacking some very basic features, and I'm not completely sure about the design heirarchy just yet. But I'll go ahead and post what I've got so far as a sort of proof-of-concept. Also, it isn't yet set up to load/alter programs. So basically, you'll need to enter a long sequance of commands (no line numbers) on a single line (I know this limits testing capabilities quite a bit, so I'll try to repost a better driver soon).

    [edit]
    Hmm, seems I've introduced a bug after paring it down for posting. I'll post a fix shortly...
    [/edit]

    [edit2]
    Ah, it's just that if you forget to follow a FOR with a NEXT you get a stack underflow.

    Oh, and one more thing, you can view each instruction as it gets executed by invoking the DEBUG command...
    [/edit2]
    Last edited by Sebastiani; 04-10-2009 at 07:48 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;
    }

  7. #172
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I had a 5 minute look, and it looks good.

    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.

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

  8. #173
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    One comment:
    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.

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

  9. #174
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    This is pretty close to how I originally envisioned it, but I didn't want to start you guys on that road in case I didn't have enough time to help.

    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.

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

    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.

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

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

    Soma

  10. #175
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by phantomotap
    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.
    hmm... as in you will only help if the the project is licensed under GPLv3, but not if it is licensed under any other Free Software/Open Source license?

    Quote Originally Posted by phantomotap
    Edit: Er... and not that it matters, but my name is Zero Valintine.
    Tsk, you should have done that Bond style
    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

  11. #176
    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;
    }

  12. #177
    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.)

  13. #178
    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.

  14. #179
    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:
    };

  15. #180
    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;
    }

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