Mercerenies / gdlisp

Lisp on the Godot platform
GNU General Public License v3.0
141 stars 1 forks source link

Duplicate Modifiers Result in Odd Parses #36

Closed Mercerenies closed 3 years ago

Mercerenies commented 3 years ago

Our current method for ensuring that modifiers such as public, private, main, or static are not applied multiple times is a bit sloppy. In particular, consider the following snippet.

(defconst private 1)
(defn foo () public private)

It should be an error to provide a public and private visibility modifier to the same function. But because of the way parsing modifiers works right now, the public gets parsed, then the private parse fails, so private is considered the body of the function, which is a constant name that exists and hence is allowed.

We need to separate modifier::ParseError into fatal and non-fatal parse errors. Non-fatal parse errors are things like "I was looking for public but got private" and allow other alternatives to run. Fatal parse errors are things like "I parsed two privates in a row" and should abort the parse with a full GDLisp compile error immediately. Effectively, we currently have one ParseError "error monad" which works with the parser, and we need another one that circumvents the parser entirely.

Mercerenies commented 3 years ago

Incidentally, if you actually want to refer to a variable called private at the beginning of your function for some inexplicable reason, then progn saves the day.

(defconst private 1)
(defn foo () public (progn private))

This is the "intended" way to get the current, erroneous behavior the first snippet exhibits.