6
retoor
141d

Once again lost source of retoorscript. Wasn't that mad about it, there was some stuff that could've been better anyway.

I wrote a whole new interpreter in 48 hours or so.

It supports user defined functions and native functions that you can add to the VM yourself.

I did spend extra effort to make it faster than python. Who says python is slow never wrote a language.

It has garbage collection and it doesn't contain leaks.

Sad thing is that I have to write the string manipulation functions again. That's a lot of effort.

In the screenshot, obj is not existing, this is how you declare vars, just using it. Works directly as an object. It does keep all his properties if I would assign a value later to obj. Numbers can be property names for some reason.

It would be possible to write a webapplication with it. This requires a decent stdlib. A lot of work.

Other stuff that I'll still have to add:
- loops
- arrays
- if / else

The goal is to make the most easy understandable and easy to extend interpreter ever.

You can just do VM_register(vm, "name", ptr_to_your_function) to add any methods.

Ideas are very welcome

Comments
  • 2
    Haha, like rust it always returns last variable. I just see that I've "return" there. Did not even implement that but still it works. Funny
  • 2
    I researched a lot and besides that scheme is a stupid language, this is the best interpreter example on the market imho: https://github.com/petermichaux/.... I just discovered it and my language isn't based on it but it does look a like a bit in source code. It has the simplicity I'm going for. An understandable interpreter, that's the art!
  • 1
    fun! Can obj then be assigned as a value? Are these objects reference types? Do functions see the object they're being called on, and/or do they have lexical scope?
  • 1
    @lorentz yes, you can assign to object. They're not reference types, when you assign, the value gets copied, functions don't see object. Classes will come later. I didn't work on scopes yet. The project is just started. I just implemented neq, eq, if, while, increment and decrement. All this is implemented using the plugin system. If you're on Matrix I can share source
  • 1
    I‘m a simple man. I see a language without semicolons, I hit ++.
  • 1
    @Lensflare yeah, there's really no need for semicolons. If theres no operator, nothing to parse further
  • 1
    @lorentz this is how I manage to keep the main interpreter small and clean. All functions are just nicely plugged in. I want to have socket support - without a nice plugin system it would mess up the whole project. The main application is just 50 lines long
  • 1
    @retoor That is a very nice API indeed. I'm trying to keep plugins as separate compilation units to save plugin devs from having to recompile the interpreter and all the other plugins they might depend on.

    I have a bad habit of trying to solve problems before verifying that they exist, but this one definitely did exist after a bit of expansion, so watch out for your compile times! C++ has better compile times than Rust, but I'm not sure it scales differently and I hit the wall very quickly.
  • 1
    wait, is that C or C++? The context being passed as a parameter suggests C. If it is C, dynamic linking isn't an issue so my warning is irrelevant.
  • 1
    I got matrix specifically for this, it's on my profile, I will not link it here because rant pages are indexed by search engines and I don't want my DevRant to pop up when searching my nickname.
  • 0
    @lorentz come here: https://matrix.to//...

    Project is in C indeed. I don't like C++. C has all you need
  • 2
    @lorentz at this moment I'm having trouble to get double char operators in my lexer. It's really not made to lex ==,!=, >=, ++
  • 2
    @retoor It took me like 5 attempts to come up with a lexer design that doesn't suck, it's the simplest, dullest solution you could imagine with strip_prefix, basic tests, and passing the remaining text around.

    At some point lexer errors tracked location data from the back of the string to avoid a context object, but then I wanted lexer plugins which needed to be kept somewhere and they had to be able to call back to the original lexer for recursion in template strings so instead I have a context object that can also convert between various location formats to ensure that errors are produced with the obvious indexing from the get go.
  • 2
    Actually, I'm pretty sure the current orchid lexer doesn't know the possible operators and just lexes contiguous sequences of characters that aren't name-legal and don't have another meaning as operators, with the idea being that writing operators right next to each other is confusing anyway and the interpreter shouldn't be smarter than the human reader.
  • 1
    @retoor I‘m a total noob on this topic but isn‘t a tokenizer supposed to do that?
  • 1
    @Lensflare yes, a lexer. I have it build now. == && != works as do if and while. Had a huge bug - ignored all tokens containing a new line and a space. This is nice - you want that, but not if they're a string. I had hard time to figure out why print("test", "\n") wasn't working but print("test", "pony\n") was. I applied that white space filter long ago so would've never expected there.

    My new lexer functionality is a bit slower. Still my interpreter is faster than python and want to keep it that way. Benchmarking often. The smallest innocent change can fuck you up performance wise
  • 1
    @lorentz

    C does have dynamic linking, and has the same pitfalls. (Making sure you don't load different versions of the same library) What C++ has that C doesn't is name mangling (required to allow overloading).

    As for compilation times, C++ suffers mostly from the STL and templates being code gen in disguise, and headers being just text inclusion. Rust should be better if it has decent module handling.

    Hopefully C++ modules will help with that.
Add Comment