Skip to content
This repository has been archived by the owner on Nov 11, 2021. It is now read-only.

Partial Block Macros Not Possible #72

Open
IHateYourCode opened this issue Sep 30, 2021 · 7 comments
Open

Partial Block Macros Not Possible #72

IHateYourCode opened this issue Sep 30, 2021 · 7 comments

Comments

@IHateYourCode
Copy link

macro ifSmaller
< if
end

'Half' macros like this sadly don't work currently

As far as I can see, the lexer goes through the macro
content and actually evaluates the if end sequence
instead of ignoring it until all macros are expanded.

Correct me if I'm wrong.

@drocha87
Copy link
Contributor

What are the benefits this approach brings to the language? ifSmaller is bigger than and harder to read than < if.

Other thing is how macro should guess that this end is to close the macro itself and not the if? Should we introduce a end_macro keyword?

IMO introducing this kind of syntactic sugar to the language at this point will just make a lot harder to implement the language in itself in the future.

@IHateYourCode
Copy link
Author

It allows for macros that can extend the head of any block statement,
which opens quite a lot of possibilities.

Yes ifSmaller is longer than < if and I wouldn't call it that if I were
to use it, that misses the point though. The point is it abbreviates an
expression and makes it more readable, again I 'ifSmaller' was only
and example.

No, I of course wouldn't suggest a separate keyword for that, it's not
needed for something like that, there are multiple ways to handle this.

Going by 'macros can only be implemented in top lvl scope' (not sure
if nested macros were allowed), you could go by identation, something
like:

'Macros can be written as one liners, in which case they end at the
current end of the line or if stretched over multiple lines have to be closed with
the keyword end and their content has to be indented'
this would force indentation, which isn't nice, tho on the other hand
if you write a macro over multiple lines, not identing isn't something
you should do anyways.

A second approach could be the one C takes, similar one-liner policy
but multiline proof through backslashes at the end of each line that
should be continued.

Macros aren't anything new, neither is this problem, other languages
offer existing, working solutions.

Personally I'd go for the second solutions since it's quite clean if
one alines the backslashes.

'at this point will just make a lot harder to implement the language in itself in the future.'
For a compiler, integral changes should be made ealier than later, considering how
hard it may later become.

@cg-jl
Copy link

cg-jl commented Oct 3, 2021

I think that this is not really necessary. I don't see myself in a scenario where this would be useful.

Aside from that, I wanted to point out a couple things:

Going by 'macros can only be implemented in top lvl scope' (not sure
if nested macros were allowed), you could go by identation

The language isn't indentation based, this isn't python. The language is meant to identify blocks by having a keyword that starts the block (macro, if, while) and having an end keyword that signifies 'end of the current block'. It's meant to be a simple language, straightforward to lex, parse, and compile. Scope-based macros would be a nice thing if... there were actual reasons to scope them (such as modules inside modules, functions). Macros inside macros aren't possible because the contents of the macro is meant to be a list of tokens.

As for the C approach, I don't have anything to say, except that it breaks the consistency of having block_start ... end define a comprised list of tokens that the language seems to be following.

@IHateYourCode
Copy link
Author

IHateYourCode commented Oct 3, 2021

As for the C approach, I don't have anything to say, except that it breaks the consistency of having block_start ... end define a comprised list of tokens that the language seems to be following.

Not quite, if you go with the following example code

macro ifTrue \
    dup 1 =   \
end

You can see that any line that is not supposed to be lexed,
within the macro is followed by a \. This doesn't remove
the end keyword, it just helps the compiler know where not
to search for it.
So it starts by seeing the macro keyword, uses the next token
as the macro name, and following that it checks if the current
line ends with a backshlash. For as long as each next line ends
that way, the compiler ignores the lines (just takes note of them)
and continues.
Once a lines without backshlash appears it starts lexing again,
finding the end keyword like normal and closing the macro.
Now, in the expansion of the macro, the backslahes are simply
removed, allowing for the content to be lexed.

@IHateYourCode
Copy link
Author

Other examples:

macro repeat         \
    while dup 0 < do \
        1 -          \
end
5 repeat
    "test\n" 1 1 syscall3 drop
end

@Domkeykong
Copy link

Domkeykong commented Oct 10, 2021

allowing if or other blocks inside a macro allows to create min and max macros:

macro max 2dup > if drop else swap drop end end

macro min 2dup < if drop else swap drop end end

@0dminnimda
Copy link

0dminnimda commented Oct 12, 2021

I think that this is not really necessary. I don't see myself in a scenario where this would be useful.

That's as I see right now mostly for ease of the writing code.
For example you wanna implementation python-like range and be able to do such thing

1 10 2 for_range
  dup print
end drop drop drop
// 1 3 5 7 9

You can do this with partial while in the for_range

// in: start end step
macro for_range
  // end step (start - step)
  rot over -
  // end step num
  while
    // end step (num + step)
    over +
    // step (num + step) end
    rot
    // end step (num + step) ((num + step) < end)
    if 2dup < do
      rot rot true
    else
      rot rot false
    end
  do
  // no `end` for `while`
end

So obviously your code gonna become nightmare if you will just expand this macro by hand every time you want this behaviour (image two nested ranges), and all that is because of impossibility to use partial macros.


Yeah, that not complete implementation of python range, because it doesn't work with negative step, but you got the idea.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants