|
Post by felixp7 on Nov 14, 2019 8:39:16 GMT 1
I love making interpreters. It's one of the first things I try when learning a new programming language. It's fun, and leaves you with a native scripting engine, which has advantages over embedding one via the foreign function interface. Question is, what language could be implemented in BaCon without undue effort? Turns out, one answer is Forth. Now, I'm not very fond of Forth. I've read books about it; studied several dialects; even created my own for a tutorial. It still looks incomprehensible to me, even when using modern programming techniques to straighten up those ass-backwards control structures. That said, keeping it simple helps a lot: not all languages have to do everything! And between delimited strings and PUSH/PULL statements, BaCon seems ready-made to implement a Forth. What you have in the attached file was typed in two hours this morning (not counting last evening's research session). Likely it could be done better, and see the comments for a couple of issues I ran into. Any advice would be welcome. Plans for the immediate future involve: - colon definitions;
- variables;
- string support;
- conditionals;
- simple looping.
Also note the use of ME$ to make the interpreter work both embedded and stand-alone. Obviously, even if you embed it, only one interpreter context can exist per application. But that's a much smaller limitation than it seems. Have fun, and let me know what you think. Thank you. Attachments:forth.bac (3.48 KB)
|
|
|
Post by Pjot on Nov 14, 2019 22:23:48 GMT 1
Thanks felixp7, Interesting! Now I first need to learn how to program Forth Best regards Peter
|
|
|
Post by vovchik on Nov 14, 2019 22:35:11 GMT 1
Dear felixp7, My thanks, too! Like Peter, I don't remember much forth do but recall dabbling with it a little decades ago. I like it that you managed to do a partial implementation in some 240 lines of code. Impressive. With kind regards, vovchik PS. I think this might point the way to various interpreters written in BaCon that could be used for scripting. Parsing/lexing would require some work, though.
|
|
|
Post by felixp7 on Nov 15, 2019 8:33:06 GMT 1
Thank you so much for the kind words! I got way ahead of myself with the first attempt, and had to back up a little. The result is a version with less code but more capabilities: comments, variables and typing out strings. I left out comparison and logical operators, since those are pointless without conditionals. Some differences from a "real" Forth: - it has proper quoted strings, like in Basic!
- `type` takes a token from the input buffer, instead of typing out the scratch pad or whatever; this may change;
- comments are via a `rem` word, which does nothing but swallow the next token from the input buffer;
- variables work differently too: `! my-var` stores the top of the stack in a variable called my-var, and plain `my-var` pushes its value back on the stack;
- `execute` does something different; this too might have to change.
In the way of implementation, I switched from FOR ... IN to iterating with HEAD$ and LAST$, which also happens to make quoted strings work right, as explained in this thread. Last but not least, a little code sample for Peter: ? type "3 + 2 = " 3 2 + . cr 3 + 2 = 5 ok ? 3 2 + ! a type "a = " a . cr a = 5 ok
Enjoy! I'll be back with more soon. P.S. Oops, forgot to say this: if there's interest in more native scripting languages for BaCon, I have a line-number Basic dialect that should be possible to port without undue effort. Forth however is a lot quicker to bootstrap (under 40 lines of code for the core interpreter! this just blew my previous record out of the water). Attachments:min-forth.bac (3.68 KB)
|
|
|
Post by felixp7 on Nov 16, 2019 14:50:19 GMT 1
And... I'm back! Sorry for the delay; after adding colon definitions to BaCon Forth, it turned out that words like `type` and `!` couldn't work inside them. I devised a new scheme, but then real life got in the way. Turned out, it was really easy to get my idea working. As for how, the trick is as follows: there is now a `do` word, that places the next one after itself in the scratch pad. This has to be special-cased inside `execute_word`, which is why I want this to be the only one; all other words that need literal text to work with can simply look where `do` leaves it. So now printing out messages looks like this: do "Hello, world!" say cr while setting a variable looks like this: 10 do fingers ! and comments like this: do "Blah, blah" note It's no more backwards than a typical Forth, arguably less, and it all works just as well inside colon definitions: ? : hi do "Hello, world!" say cr ; ok ? hi Hello, world! ok (Though of course "comments" are executable statements, so you'll want to leave them on the outside.) More importantly, the same `do` can just as easily be the basis of control structures. Imagine being able to write code like, But maybe in a few days. Have fun, and let me know what you think. Attachments:forth.bac (5.34 KB)
|
|
|
Post by Pjot on Nov 17, 2019 11:43:14 GMT 1
Thanks felixp7, The code looks very concise, adhering to a 'minimal style' kind of programming, a style which is my favorite too. Interestingly you are making use of PUSH/PULL. I recently have been considering to remove these statements from BaCon, but they now seem to have a purpose after all BR Peter
|
|
|
Post by felixp7 on Nov 17, 2019 13:48:12 GMT 1
You're very kind! And yes, the whole idea was to do everything the BaCon way as much as I could. Hence using its built-in data stack, associative arrays, and especially delimited strings. Speaking of which: I tried using DOTIMES, and ran into what seems to be a bug. Trying to compile this little test program: DOTIMES 10 PRINT _ DONE results in the following error message: It seems the anonymous variable _ isn't in fact made available inside the loop like the docs say it should be. No biggie, I just used FOR instead. Otherwise, I added the control structures as described previously, and a bunch of other words that can be used for metaprogramming. They don't really work like in most Forths, but documentation will have to wait. Next, loading from files and a few other conveniences, then a web page for the project. Enjoy! Attachments:forth.bac (7.7 KB)
|
|
|
Post by Pjot on Nov 17, 2019 18:00:27 GMT 1
Speaking of which: I tried using DOTIMES, and ran into what seems to be a bug. Trying to compile this little test program: DOTIMES 10 PRINT _ DONE results in the following error message: That's right - you need BaCon 3.9.3 to use the anonymous variable in DOTIMES. The upcoming 3.9.3 is still in beta, but you can fetch it using this instruction. BR Peter
|
|
|
Post by felixp7 on Nov 18, 2019 7:27:55 GMT 1
Oh, all right! It would be nice if the manual said when each feature was added, like the Python docs do ("new in version X.Y"). Anyway, the most disruptive change in this version is that I renamed `say` back to `type`. There was no reason to be different in this case. I also fixed an error whereas the big regular expression at the top didn't recognize negative numbers! How did I miss that before? And of course added more words, among which \ (backslash) for end-of-line comments (not tested inside definitions yet, but it should work) and `words` to get a list of everything in the dictionary. Well, it doesn't include variables yet. Last but not least, I rewrote the code for math and logic operators so they pull operands from the stack in the right order and make the code read naturally. Tests will soon be a necessity. But first to add an `include` word, and before that, to start working on a web page for the project. Cheers. Attachments:forth.bac (8.98 KB)
|
|
|
Post by Pjot on Nov 18, 2019 19:25:51 GMT 1
It would be nice if the manual said when each feature was added, like the Python docs do ("new in version X.Y"). The online documentation clearly mentions "BaCon 3.9.3 beta documentation". The reason for this is as follows: as the beta version often contains new features, users start asking how these new features can be used. Therefore, by request of multiple users, they are already documented online. However, for your specific release, the man page which comes with the BaCon install package actually does contain the documentation for your specific release. Please note that BaCon is not maintained by a group of well-paid developers, like in case of Python (or Go, Rust, Java or any other major language). It is a project which is created and maintained in spare time and therefore should be considered as "best effort". It simply takes a lot of time and effort to maintain multiple versions of documentation in several releases. But it's flattering that you compare BaCon with Python though Also note that you can always verify the latest CHANGES file in the development tree (click bacon_trunk->doc-pak->CHANGES) which mentions the upcoming features for the upcoming release. This way you can exclude documentation which is not applicable to your specific version. HTH, Peter
|
|
|
Post by felixp7 on Nov 18, 2019 20:34:51 GMT 1
I've noticed the version number at the top of the manual. The changelog proved useful several times, too. I was just thinking it would be easier to spot changes if they were marked into the text, like this: You'd still have to maintain just one version of the manual, in fact that's the idea, so people can see at a glance how things evolved. But I realize BaCon is developed by a few volunteers, and doing this on top of everything else would take too much effort. Sorry, didn't mean to make demands. Anyway, in the mean time I started work on a web page for the project. There's not much yet, but until I can write more code, it might be a fun diversion.
|
|
|
Post by Pjot on Nov 18, 2019 21:46:19 GMT 1
No worries felixp7 - I just tried to explain how things grew into what has now become this project, and sketch its limitations as well. Suggestions and remarks which add to the quality of BaCon are always welcome! The website looks good, stylish and sober, as I like myself too. Hope the Forth project will give us, and above all, you yourself, a boost into new discoveries
Please keep posting your findings and remarks if you run into problems.
Best regards Peter
|
|
|
Post by felixp7 on Nov 19, 2019 9:52:39 GMT 1
Glad you like my web design, and my coding style too! I wasn't feeling up to it this morning, but in the end managed to add the rest of what I had plans for, like a conditional loop and `include` word. Now it's finally possible to add a test suite, at least on the Forth side. (Had to change the code such that now `forth_interpret` no longer prints "ok" by itself.) Beware that error checking is non-existent. As for what's next, I plan to focus on making a public release (it will be MIT-licensed, partly to stay compatible with BaCon), then to write a blog post for my gamedev site. Speaking of which, what I learned by making BaCon Forth should serve me well soon. Then to polish the code some, add checks and tests and documentation, the works. If anyone finds BaCon Forth useful, I'd love to hear from you. The plan is to keep the core interpreter a single-file library (and not too big), though optional word sets would be welcome. Also to keep using PUSH/PULL, unless Peter decides to remove them. That does mean not being able to see how many items are on the stack, or what they are, but oh well. It would also be ideal if any additions kept close to ANS Forth where possible, at least in using similar words for similar purposes, like with `?again` and `?exit`. Otherwise, back soon, and thanks again! Attachments:forth.bac (9.85 KB)
|
|
|
Post by felixp7 on Nov 20, 2019 6:56:25 GMT 1
Well, guess there was still more to be done after all. Bunch of incompatible changes in fact. Good thing this is still labeled an alpha version. To wit: - Renamed `expect` to `accept`; didn't know the former was obsolete.
- Renamed `buffer?` to `source` and `pad?` to `count`.
- Removed `note` in favor of proper Forth comments (in parentheses).
I still have one more word to add, and some reorganization to do, but that's minor and can probably wait for the first public release. (Editing this post to link said public release since the discussion has died down.) Attachments:forth.bac (10.35 KB)
|
|