marcobambini / gravity

Gravity Programming Language
https://gravity-lang.org
MIT License
4.29k stars 228 forks source link

[Feature Req] Class Constructor/Destructor, Custom Macros via Delegate #362

Closed akamicah closed 3 years ago

akamicah commented 3 years ago

Hi there :) Two parts to this one;

First: Constructor/Destructor for Classes. I do believe this would be very useful if for instance you want to initialise class properties using logic rather than hard coded values.

Secondly: delegate for custom macros handling (I did bring this up in https://github.com/marcobambini/gravity/discussions/359 however it seems discussions is rarely used).

It could certainly allow extensibility by allowing preprocessing of source code for any use such as passing information to the host application.

I mentioned in the discussion about perhaps having the delegate have a boolean return value (true: custom macro handled, false: custom macro failed), but after thought, it seems more fitting to have it return a 'const char*'. If the returned array is NULL then it can be treated as an unhandled macro and throw an error accordingly, if it's string then it could replace the macro with the provided string.

The big challenge I see with this is knowing what to pass through as a value with the macro. I suppose if anything exists after the macro and whitespace then pass that up until either a newline, semicolon, or even a bracket closure maybe? that would perhaps allow for a feature like;

#define Something "Hello, World";
...
System.print(#Something);  // Output: "Hello, World"

If the host application were to handle #define macros by evaluating the string value for a name proceeded by a value, and then upon handling a macro contained in that map, return the associated value... possibly

Kind regards

marcobambini commented 3 years ago

Hi @MikeRKing,

  1. Constructor/Destructor for Classes is already implemented, see init and deinit (like in Swift).

  2. Delegate for custom macro handling is a very interesting feature and it is something I considered when I implemented the language. It turns out that I needed a couple of macros only and that's the main reason why I haven't implemented a more flexible delegate method.

The return value should be true/false only (with false that triggers a return value). A hash table could be used to pass information between different macros in different parts of the code.

The #ifdef/#elif/#endif macro behavior would introduce a lot of complexity, so I need to carefully think about the pros/cons of the macro delegate behavior.

akamicah commented 3 years ago

In that case, ignore the first feature request, but it would appear that destructors are not implemented, so deinit() would not be called upon an object going out of scope

As for macros, I suppose you could still implement a delegate to handle non-special macros (like #include, and any others that get added over time) by just calling upon the delegate under MACRO_UNKNOWN - if boolean is used then just returning NULL if the return is true

case MACRO_UNKNOWN:
    if(parse_custom_macro(parser)) return NULL;
    break;
marcobambini commented 3 years ago

@MikeRKing I added support for deinit destructors with https://github.com/marcobambini/gravity/commit/4a28251ec88a32ec073394078ee8a4c192cc090d