I’m creating a syntax definition for Alan, an Interactive Fiction authoring language. I’m no syntax expert, but with the help of users from the forum I’m starting to make my way through scope name choices and best practices.
I’m implementing the sytnax constructs using arbitrary scope names until I understand which are the correct choices, and I’d like some help to fix the scope names before the project grows too much. My problem is mainly due to lack of experience on how to determine the right scope a syntax construct belongs to, as well as handling the scope name segments.
The Alan language is a class-based programming language, so the distinction between Class and Instance is significant (especially for plugins and scope selectors). Also, all instances are statically created at game-start, and no new instances can be created during play (ie dynamically).
So far, with help from this forum, I’ve managed to scope class declarations correctly. Where the declaration of a class being:
EVERY book IsA object.
-- here go class-level attributes, verbs, checks, etc.
END EVERY book.
… is being scoped as:
EVERY book IsA object. -- comment
--^^^ meta.class.alan storage.type.class.alan
-- ^^^^^^ meta.class.alan entity.other.inherited-class.alan
-- ^ meta.class.alan punctuation.terminator.alan
-- ^^^^ meta.class.alan entity.name.class.alan
-- ^^^ meta.class.alan storage.modifier.extends
END EVERY book.
-- ^^^^^^^^^^^^ meta.class.alan
-- ^^^^ entity.name.class.tail.alan
-- ^ punctuation.terminator.alan
Instance Construct
An instance will be declared with this syntax:
THE cake IsA object.
-- here go instance-specific attributes, verbs, checks, etc.
END THE cake.
As a temporary solution I’ve scoped this way (just to get the job done):
THE cake IsA object. -- comment
--<- meta.instance.alan storage.type.instance.alan
-- ^^^^^^ meta.instance.alan entity.other.inherited-class.alan
-- ^ meta.instance.alan punctuation.terminator.alan
-- ^^^^ meta.instance.alan entity.name.instance.alan
-- ^^^ meta.instance.alan storage.modifier.extends
END THE cake.
-- ^^^^^^^^^^ meta.instance.alan
-- ^^^^ entity.name.instance.tail.alan
-- ^ punctuation.terminator.alan
I’ve tried my best in reading docs from various sources, but the whole question of what an instance actually is seems to be at the center of a semantic debate in various languages. I seem to understand that at the end of the day it’s just a type of variable, but in this specific interactive fictions languages there are basically only classes, instances, attributes, verbs and events (plus a few native types like booleans, string, and sets), so if it’s not a big “no-no” I’d like to keep the word instance
somehow.
At this project, I’ve found some real case uses of instance
in scopes:
So I wanted to get some advice on which would the right choice balancing the benefits of sticking to standard scope names and the specific needs of the language package — eg, having the right scopes to handle things like autocompletion, and plugins that are specifically thought for this syntax. Being an interactive ficiton syntax, I doubt it might be making use of many plugins; and even for color schemes, since it’s a mixture of light-code and prose, dedicated color schemes are most likely the best choice.
The “ADD TO” Construct
Another syntax construct which I’ve already covered with temporary scope names is the ADD TO construct, which is used to change/add an already defined class (you can use all the same constructs as in a class declaration, except that the class must exists beforehand).
An example:
ADD TO EVERY toy
-- some class-level additions and overrides (attributes, verbs, checks, etc.)
END ADD TO toy.
As a temporary solution, I’ve scoped the whole block as meta.addition.alan
:
ADD TO EVERY toy
^^^^^^^^^^^^ storage.modifier.extends.alan
^^^ entity.name.class.alan
END ADD TO toy.
^^^^^^^^^^ keyword.control.alan
^^^ entity.name.addition.tail.alan
What meta
scope should I use for this? It seems to me that it is a class construct after all, but I’d like to be able to distinguish it from a class declaration in scope-selectors.
Can I add an extra scope to both the class declaration block (eg: meta.class.declare
) and to this one (eg: meta.class.extend
) so that they share a common segment, but also can be distinguished one another?
Should the class identifiers here have a different class
scope from the class declaration block (eg: entity.name.class.extend.alan
)?
Thanks for your help.