plum

#treesitter#compiler#wasm

git clone https://git.pyrossh.dev/plum

A statically typed, imperative programming language inspired by rust, python


plum-tooling/vscode-plum/syntaxes/plum.tmLanguage.json
{
  "name": "plum",
  "scopeName": "source.plum",
  "patterns": [
    {
      "include": "#comments"
    },
    {
      "include": "#keywords"
    },
    {
      "include": "#constant"
    },
    {
      "include": "#string"
    },
    {
      "include": "#raw_quoted_string"
    },
    {
      "include": "#number"
    },
    {
      "include": "#entity"
    },
    {
      "include": "#discards"
    }
  ],
  "repository": {
    "comments": {
      "patterns": [
        {
          "name": "comment.line.plum",
          "match": "#.*"
        }
      ]
    },
    "keywords": {
      "patterns": [
        {
          "match": "\\b(module|enum|trait|fun|self|test)\\b",
          "name": "keyword.const.plum"
        },
        {
          "name": "keyword.control.plum",
          "match": "\\b(import|in|return|continue|break|match|when|if|else|while|for|assert|todo)\\b"
        },
        {
          "name": "keyword.operator.range.plum",
          "match": "\\.\\."
        },
        {
          "name": "keyword.operator.splat.plum",
          "match": "\\.\\.\\."
        },
        {
          "name": "keyword.operator.comparison.plum",
          "match": "(==|!=|<=|>=|<|>)"
        },
        {
          "comment": "elvis (Result/Option unwrap-or-fallback) — checked before the bare `?` try-operator below, since `?:` must win the longer match",
          "name": "keyword.operator.elvis.plum",
          "match": "\\?:"
        },
        {
          "comment": "safe navigation (Result/Option `.map` sugar) — checked before the bare `?` try-operator below, since `?.` must win the longer match",
          "name": "keyword.operator.safenav.plum",
          "match": "\\?\\."
        },
        {
          "comment": "postfix try-operator (Result/Option unwrap-or-early-return) — matched only when `?` glues directly to the preceding token with no space, `plum format`'s own convention for this postfix operator (unlike ternary's `?`, always spaced); ternary's own `?`/`:` are deliberately left unstyled here too, matching the tree-sitter highlights.scm, since a regex can't reliably tell them apart",
          "name": "keyword.operator.try.plum",
          "match": "(?<=[A-Za-z0-9_\\)\\]])\\?(?!:)(?!\\.)"
        },
        {
          "name": "keyword.operator.logical.plum",
          "match": "(&&|\\|\\|)"
        },
        {
          "name": "keyword.operator.arithmetic.plum",
          "match": "(\\+|\\-|/|\\*|%)"
        },
        {
          "name": "keyword.operator.assignment.plum",
          "match": "="
        }
      ]
    },
    "constant": {
      "patterns": [
        {
          "comment": "ALL CAPS constants",
          "name": "constant.other.caps.plum",
          "match": "\\b[A-Z]{2}[A-Z0-9_]*\\b"
        },
        {
          "comment": "constant declarations",
          "match": "\\b\\s+([A-Z_]*)\\b",
          "captures": {
            "1": {
              "name": "storage.type.plum"
            },
            "2": {
              "name": "constant.other.caps.plum"
            }
          }
        }
      ]
    },
    "number": {
      "name": "constant.numeric.plum",
      "patterns": [
        {
          "include": "#number-float"
        },
        {
          "include": "#number-dec"
        },
        {
          "include": "#number-hex"
        },
        {
          "include": "#number-bin"
        },
        {
          "name": "invalid.illegal.name.plum",
          "match": "\\b[0-9]+\\w+"
        }
      ]
    },
    "number-float": {
      "name": "constant.numeric.float.plum",
      "match": "(?x)\n  (?<! \\w)(?:\n    (?:\n      (?:[0-9]+(?:_+[0-9]+)*)? \\. [0-9]+(?:_+[0-9]+)* (?: [eE][+-]?[0-9]+(?:_+[0-9]+)* )?\n      |\n      [0-9]+(?:_+[0-9]+)* [eE][+-]?[0-9]+(?:_+[0-9]+)*\n    ) ([fF])?\n    |\n    [0-9]+(?:_+[0-9]+)* ([fF])\n  )\\b\n",
      "captures": {
        "1": {
          "name": "storage.type.number.plum"
        },
        "2": {
          "name": "storage.type.number.plum"
        }
      }
    },
    "number-dec": {
      "name": "constant.numeric.dec.plum",
      "match": "(?x)\n  (?<![\\w\\.])(?:\n      [1-9](?: _?[0-9] )*\n      |\n      0+\n      |\n      [0-9](?: _?[0-9] )* ([jJ])\n      |\n      0 ([0-9]+)(?![eE\\.])\n  )\\b\n",
      "captures": {
        "1": {
          "name": "storage.type.imaginary.number.plum"
        },
        "2": {
          "name": "invalid.illegal.dec.plum"
        }
      }
    },
    "number-hex": {
      "name": "constant.numeric.hex.plum",
      "match": "(?x)\n  (?<![\\w\\.])\n    (0[xX]) (_?[0-9a-fA-F])+\n  \\b\n",
      "captures": {
        "1": {
          "name": "storage.type.number.plum"
        }
      }
    },
    "number-bin": {
      "name": "constant.numeric.bin.plum",
      "match": "(?x)\n  (?<![\\w\\.])\n    (0[bB]) (_?[01])+\n  \\b\n",
      "captures": {
        "1": {
          "name": "storage.type.number.plum"
        }
      }
    },
    "entity": {
      "patterns": [
        {
          "name": "entity.name.type.plum",
          "match": "[[:upper:]][[:alnum:]]*"
        },
        {
          "begin": "\\b([[:lower:]][[:word:]]*)\\b\\(",
          "end": "\\)",
          "patterns": [
            {
              "include": "$self"
            }
          ],
          "captures": {
            "1": {
              "name": "entity.name.function.plum"
            }
          }
        },
        {
          "name": "variable.parameter.plum",
          "match": "\\b([[:lower:]][[:word:]]*):\\s"
        },
        {
          "name": "entity.name.namespace.plum",
          "match": "\\b([[:lower:]][[:word:]]*):"
        }
      ]
    },
    "string": {
      "patterns": [
        {
          "name": "string.quoted.double.plum",
          "begin": "\"",
          "beginCaptures": {
            "0": {
              "name": "punctuation.definition.string.begin.plum"
            }
          },
          "end": "\"",
          "endCaptures": {
            "0": {
              "name": "punctuation.definition.string.end.plum"
            }
          },
          "patterns": [
            {
              "include": "#template-substitution-element"
            },
            {
              "include": "#string-character-escape"
            }
          ]
        }
      ]
    },
    "string-character-escape": {
      "name": "constant.character.escape.plum",
      "match": "\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|u\\{[0-9A-Fa-f]+\\}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.|$)"
    },
    "template-substitution-element": {
      "name": "meta.template.expression.plum",
      "begin": "\\{",
      "beginCaptures": {
        "0": {
          "name": "punctuation.definition.template-expression.begin.plum"
        }
      },
      "end": "\\}",
      "endCaptures": {
        "0": {
          "name": "punctuation.definition.template-expression.end.plum"
        }
      },
      "patterns": [
        {
          "include": "#expression"
        }
      ],
      "contentName": "meta.embedded.line.plum"
    },
    "expression": {
      "patterns": [
        {
          "match": "\\b(self)\\b",
          "name": "keyword.const.plum"
        },
        {
          "match": "(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*(\\#?[[:upper:]][_$[:digit:][:upper:]]*)(?![_$[:alnum:]])",
          "captures": {
            "1": {
              "name": "punctuation.accessor.plum"
            },
            "2": {
              "name": "punctuation.accessor.optional.plum"
            },
            "3": {
              "name": "variable.other.constant.property.plum"
            }
          }
        },
        {
          "match": "(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*(\\#?[_$[:alpha:]][_$[:alnum:]]*)",
          "captures": {
            "1": {
              "name": "punctuation.accessor.plum"
            },
            "2": {
              "name": "punctuation.accessor.optional.plum"
            },
            "3": {
              "name": "variable.other.property.plum"
            }
          }
        },
        {
          "name": "variable.other.constant.plum",
          "match": "([[:upper:]][_$[:digit:][:upper:]]*)(?![_$[:alnum:]])"
        },
        {
          "name": "variable.other.readwrite.plum",
          "match": "[_$[:alpha:]][_$[:alnum:]]*"
        }
      ]
    },
    "raw_quoted_string": {
      "comment": "Raw string literals",
      "begin": "`",
      "beginCaptures": {
        "0": {
          "name": "punctuation.definition.string.begin.go.mod"
        }
      },
      "end": "`",
      "endCaptures": {
        "0": {
          "name": "punctuation.definition.string.end.go.mod"
        }
      },
      "name": "string.quoted.raw",
      "patterns": [
        {
          "include": "#string_placeholder"
        }
      ]
    },
    "string_placeholder": {
      "patterns": [
        {
          "match": "%(\\[\\d+\\])?([\\+#\\-0\\x20]{,2}((\\d+|\\*)?(\\.?(\\d+|\\*|(\\[\\d+\\])\\*?)?(\\[\\d+\\])?)?))?[vT%tbcdoqxXUbeEfFgGsp]",
          "name": "constant.other.placeholder.go.mod"
        }
      ]
    },
    "discards": {
      "name": "comment.unused.plum",
      "match": "\\b_(?:[[:word:]]+)?\\b"
    }
  }
}