Sublime Forum

[Syntax] Custom function declaration

#1

I’ve been throwing myself at this for the better part of a week already, but the thing that needs to click to get to my a-ha moment, just simply isn’t clicking and it seems like it’s not going to any time soon.
Basically I’m trying to alter my syntax-definitions to support Allman, I need a syntax example that will match the following:

A normal function declaration looks like this:

func(a = 2, b = 3)
{
	return a + b
}

That is:

  • [[:alnum:]] function name
  • unconditionally followed by an open-paren
  • an occurrence of an additional ( ) { } [ or ] inside the argument list is impossible
  • close-paren
  • open-brace

Now, a function declaration may, however, very well look like this as well:
https://pastebin.com/3jwWTAnm
That is:

  • begins at the start of the line or a mix of space/tab indentation is allowed
  • [[:alnum:]] function name
  • unconditionally followed by an open-paren
  • an occurrence of an additional ( ) { } [ or ] inside the argument list is impossible
  • arguments can be split and can appear on any line thereafter
  • if the above is true, single-line comments can also appear on any line there after or can appended to the end of the argument
  • close-paren, can also appear on a separate line, followed by a comment is allowed
  • open-brace, can be followed by a comment

Now the last tricky bit has to do with regular function calls:

builtInFunc(callToSomeFunc(), ["array", "argument"], {"hash": "map", "argument": 42})

There is a rare edge case whereby one might intentionally introduce a block scope after a function call which would throw it off and make it seem as though it were a function definition, but this can be ignored, as I havent been able to come up with a workaround for it:

builtInFuncAdd(var1, var2) // normal function call
builtInFuncAdd(var3, var4) // oooops, this is now a function declaration, overwriting the actual built in function
{
  // some random block scoping for no reason
}

Basically, the problem is that there’s no way to correctly match the open-brace.
I tried something like this:

  functions-declaration:
    - match: '^\s*(\w+)\(' # from start of line, however many space/tabs, alnum function name, followed by open-paren
      captures:
        1: entity.name.function.my-lang
      push:
        - match: '[^)]\)' # consume the argument list
          push:
            - match: '{'
            - meta_content_scope: invalid # just to highlight for vis. purposes
              pop: true

which fails horribly. I need something to be able to say, “hey, if theres a (){}[] inside the parameter list, abort abort”, yet at the same time account for the fact that the arguments could appear on different lines and can have comments, which might include an occasional ()[]{}.

thanks

0 Likes

#2

Unfortunately, this kind of syntax highlighting is impossible with Sublime Text. You may use look-ahead expressions to determine whether something should be interpreted in a certain way based on what follows, but you cannot go beyond the current line with your matches. Because the tokenizer would only know whether builtInFuncAdd(var1, var2) is a function call or a function definition after it scanned the next line for an opening brace, there is absolutely nothing you can do here. The same problem occurs when you start to split the function definition within the parens.

This is similar to lambda function definitions in JavaScript, which are also an unsolvable problem with the current system. The only thing you can do is fail gracefully, but it doesn’t seem like you’d need to do this for your syntax. And, depending on whether function calls with named arguments are allowed or not (func(a = 2, b = 3)), at least highlight those definitions properly.

0 Likes

#3

This is impossible. The parser cannot look past newlines.

Is this your own homebrew language? If so, consider adding a def or func keyword to signify the start of a function declaration. This makes things easier both for users of the language as well as for the ST parser.

1 Like