pmacs3/mode/bosatsu.py

121 lines
4.4 KiB
Python

import commands, os.path, re, string, sys, traceback
import color, completer, context, default, mode, method, regex, tab
from lex import Grammar, PatternRule, RegionRule, OverridePatternRule
from mode.python import StringGrammar1, StringGrammar2
class PackageGrammar(Grammar):
rules = [
PatternRule('whitespace', r'(?: |\t)+'),
PatternRule('name', r'[a-zA-Z_][a-zA-Z0-9]*'),
PatternRule('sep', r'/'),
]
class BosatsuGrammar(Grammar):
rules = [
# whitespace
PatternRule('whitespace', r'(?: |\t)+'),
PatternRule('eol', r'\n$'),
# basic
PatternRule('bosatsu.comment', r'#.*$'),
#PatternRule('bosatsu.integer', r'(?<![\.0-9a-zA-Z_])(?:0|-?[1-9][0-9]*)(?![\.0-9a-zA-Z_])'),
PatternRule('bosatsu.integer', r'(?:0|-?[1-9][0-9]*)(?![\.0-9a-zA-Z_])'),
# match keywords early
PatternRule('bosatsu.keyword', '(?:struct|recur|package|operator|match|import|if|forall|for|external|export|enum|else|def|_)(?![a-zA-Z0-9_])'),
# use look-behind assertion to detect package/def/operator
RegionRule('bosatsu.package', '(?<=(?<![a-zA-Z0-9_])package )', PackageGrammar, '\n$'),
PatternRule('bosatsu.def', '(?<=(?<![a-zA-Z0-9_])operator )[^:( ]+'),
PatternRule('bosatsu.def', '(?<=(?<![a-zA-Z0-9_])def )[a-zA-Z_][a-zA-Z0-9_]*'),
# detect a bunch of different syntax-y stuff + predef methods
PatternRule('bosatsu.builtin', r'(?:->|:|=|\.)(?![/%\*\-+<>!$&^|?~=:])'),
PatternRule('bosatsu.predef', r'(?:uncurry3|uncurry2|trace|times|string_Order|string_Order_fn|sub|reverse_concat|reverse|remove_key|range_fold|range|mod_Int|map_List|items|int_loop|get_key|gcd_Int|foldLeft|flat_map_List|eq_Int|empty_Dict|clear_Dict|div|concat|cmp_Int|add_key|add)(?![a-zA-Z0-9_])'),
PatternRule('bosatsu.delimiter', r'\(|\)|\[|\]|,'),
PatternRule('bosatsu.operator', r'[/%\*\-+<>!$&^|?~]+|=[/%\*\-+<>!$&^|?~=]+'),
# user-defined types and names
PatternRule('bosatsu.type', r'[A-Z][a-zA-Z_]*'),
PatternRule('bosatsu.bareword', r'[a-z_][a-zA-Z_]*'),
# python style strings
RegionRule('bosatsu.string', r'"', StringGrammar2, r'"'),
RegionRule('bosatsu.string', r"'", StringGrammar1, r"'"),
# we want to highlight everything, so show any unmatched
# characters as a syntax error
PatternRule('bosatsu.unknown', r'.'),
]
# white is for delimiters, operators, numbers
default = ('default', 'default')
# magenta is for reserved words
lo_magenta = ('magenta202', 'default')
hi_magenta = ('magenta505', 'default')
# red is for comments
lo_red = ('red300', 'default')
hi_red = ('red511', 'default')
# orange is unused
hi_orange = ('yellow531', 'default')
lo_orange = ('yellow520', 'default')
# yellow is for class names
hi_yellow = ('yellow551', 'default')
lo_yellow = ('yellow330', 'default')
# green is for strings
lo_green = ('green030', 'default')
hi_green = ('green050', 'default')
# cyan is for keywords and some operators
lo_cyan = ('cyan033', 'default')
hi_cyan = ('cyan155', 'default')
# blue is for functions and methods
lo_blue = ('blue113', 'default')
hi_blue = ('blue225', 'default')
class Bosatsu(mode.Fundamental):
description = '''
Mode for Oscar Boykin's language Bosatsu.
'''
name = 'Bosatsu'
extensions = ['.bosatsu']
grammar = BosatsuGrammar
opentokens = ('bosatsu.delimiter',)
opentags = {'(': ')', '[': ']'}
closetokens = ('bosatsu.delimiter',)
closetags = {')': '(', ']': '['}
commentc = '#'
colors = {
'bosatsu.comment': hi_red,
'bosatsu.package.name': hi_orange,
'bosatsu.package.sep': lo_orange,
'bosatsu.def': hi_cyan,
'bosatsu.integer': lo_orange,
'bosatsu.keyword': lo_blue,
'bosatsu.operator': hi_green,
'bosatsu.delimiter': default,
'bosatsu.builtin': lo_blue,
'bosatsu.predef': hi_magenta,
'bosatsu.type': hi_orange,
'bosatsu.string.start': lo_orange,
'bosatsu.string.data': hi_orange,
'bosatsu.string.end': lo_orange,
'bosatsu.unknown': ('default', 'magenta202'),
}
def __init__(self, w):
mode.Fundamental.__init__(self, w)
self.add_bindings('close-paren', (')',))
self.add_bindings('close-brace', ('}',))
self.add_bindings('close-bracket', (']',))
install = Bosatsu.install