OR-1 dataflow CPU sketch
at main 287 lines 7.2 kB view raw
1%YAML 1.2 2--- 3# dfasm.sublime-syntax — Context-aware syntax highlighting for Sublime Text 4# Version: 2 (Sublime Text 4) 5# 6# Architecture: Context stacks distinguish port numbers from literal numbers 7# using contextual scoping. All scopes suffixed with .dfasm per design spec. 8# 9# Scope mapping: 10# - Port numbers (in qualified refs): constant.numeric.port.dfasm 11# - Literal numbers (in arguments): constant.numeric.dfasm 12# - Named arg keys (dest=): variable.parameter.dfasm 13# - Opcodes: keyword.other.opcode.dfasm 14# 15# Reference: dfasm.lark grammar, asm/opcodes.py, design plan lines 156-185 16 17name: dfasm 18file_extensions: 19 - dfasm 20scope: source.dfasm 21 22variables: 23 identifier: '[a-zA-Z_][a-zA-Z0-9_]*' 24 hex_lit: '0x[0-9a-fA-F]+' 25 dec_lit: '[0-9]+' 26 opcodes: 'add|sub|inc|dec|shiftl|shiftr|ashiftr|and|or|xor|not|eq|lt|lte|gt|gte|breq|brgt|brge|brof|brty|sweq|swgt|swge|swof|swty|gate|sel|merge|pass|const|free_ctx|read|write|clear|alloc|free|rd_inc|rd_dec|cmp_sw|ior|iow|iorw|load_inst|change_tag|extract_tag|exec' 27 28contexts: 29 main: 30 - match: ';.*$' 31 scope: comment.line.semicolon.dfasm 32 33 - match: '@system\b' 34 scope: keyword.control.pragma.dfasm 35 push: pragma_params 36 37 # Flow operators must be matched before | and < separately 38 # to avoid sregex matching issues with lookbehinds 39 - match: '\|>' 40 scope: keyword.operator.flow.out.dfasm 41 42 - match: '<\|' 43 scope: keyword.operator.flow.in.dfasm 44 45 # Opcodes 46 - match: '\b(?:{{opcodes}})\b' 47 scope: keyword.other.opcode.dfasm 48 49 # Sigils push into qualified_ref contexts 50 - match: '@' 51 scope: punctuation.definition.reference.node.dfasm 52 push: qualified_ref_node_name 53 54 - match: '&' 55 scope: punctuation.definition.reference.label.dfasm 56 push: qualified_ref_label_name 57 58 - match: '\$' 59 scope: punctuation.definition.reference.function.dfasm 60 push: qualified_ref_func_name 61 62 # Macro call: #name 63 - match: '(#)({{identifier}})' 64 captures: 65 1: punctuation.definition.macro.dfasm 66 2: entity.name.function.macro.dfasm 67 68 # Strings with prefixes 69 - match: 'r"' 70 scope: storage.type.string.dfasm 71 push: raw_string 72 73 - match: 'b"' 74 scope: storage.type.string.dfasm 75 push: byte_string 76 77 - match: '"' 78 scope: string.quoted.double.dfasm 79 push: string 80 81 # Character literal 82 - match: "'" 83 scope: string.quoted.single.dfasm 84 push: char_literal 85 86 # Numbers (not in port context) 87 - match: '{{hex_lit}}' 88 scope: constant.numeric.dfasm 89 90 - match: '{{dec_lit}}' 91 scope: constant.numeric.dfasm 92 93 # Named arguments: identifier=value (AC4.4) 94 - match: '({{identifier}})(=)' 95 captures: 96 1: variable.parameter.dfasm 97 2: keyword.operator.assignment.dfasm 98 99 # Assignment operator 100 - match: '=' 101 scope: keyword.operator.assignment.dfasm 102 103 # Comma 104 - match: ',' 105 scope: punctuation.separator.dfasm 106 107 # Braces for function bodies 108 - match: '\{' 109 scope: punctuation.section.block.dfasm 110 push: func_body 111 112 - match: '\}' 113 scope: punctuation.section.block.dfasm 114 115 # Placement separator (must come after |>) 116 - match: '\|(?!>)' 117 scope: punctuation.separator.placement.dfasm 118 119 # Colon separator (in port specs, but only matched if not in qualified_ref) 120 - match: ':' 121 scope: punctuation.separator.port.dfasm 122 123 # Whitespace 124 - match: '\s+' 125 126 # === Qualified Reference Contexts === 127 # Separate contexts per sigil to enforce scope mapping 128 129 qualified_ref_node_name: 130 - match: '{{identifier}}' 131 scope: entity.name.tag.dfasm 132 set: qualified_ref_suffix 133 - match: '(?=\S)' 134 pop: true 135 136 qualified_ref_label_name: 137 - match: '{{identifier}}' 138 scope: entity.name.label.dfasm 139 set: qualified_ref_suffix 140 - match: '(?=\S)' 141 pop: true 142 143 qualified_ref_func_name: 144 - match: '{{identifier}}' 145 scope: entity.name.function.dfasm 146 set: qualified_ref_suffix 147 - match: '(?=\S)' 148 pop: true 149 150 qualified_ref_suffix: 151 # Placement: | not followed by > 152 - match: '\|(?!>)' 153 scope: punctuation.separator.placement.dfasm 154 set: placement_name 155 156 # Port: : followed by number or identifier 157 - match: ':' 158 scope: punctuation.separator.port.dfasm 159 set: port_spec 160 161 # No suffix, pop back to main 162 - match: '' 163 pop: true 164 165 placement_name: 166 - match: '{{identifier}}' 167 scope: entity.other.attribute-name.placement.dfasm 168 set: qualified_ref_suffix_after_placement 169 - match: '(?=\S)' 170 pop: true 171 172 qualified_ref_suffix_after_placement: 173 # Port after placement 174 - match: ':' 175 scope: punctuation.separator.port.dfasm 176 set: port_spec 177 178 # No port, pop 179 - match: '' 180 pop: true 181 182 port_spec: 183 # Port identifier (L, R, etc.) 184 - match: '{{identifier}}' 185 scope: entity.other.attribute-name.port.dfasm 186 pop: true 187 188 # Hex number in port position gets constant.numeric.port.dfasm 189 - match: '{{hex_lit}}' 190 scope: constant.numeric.port.dfasm 191 pop: true 192 193 # Decimal number in port position gets constant.numeric.port.dfasm 194 - match: '{{dec_lit}}' 195 scope: constant.numeric.port.dfasm 196 pop: true 197 198 # No valid port spec, pop 199 - match: '' 200 pop: true 201 202 # === Function Body === 203 func_body: 204 - meta_scope: meta.function.body.dfasm 205 206 - match: '\}' 207 scope: punctuation.section.block.dfasm 208 pop: true 209 210 # Include main context rules inside function body (AC4.5) 211 - include: main 212 213 # === Pragma Parameters === 214 pragma_params: 215 # param=value pairs 216 - match: '({{identifier}})(=)({{hex_lit}}|{{dec_lit}})' 217 captures: 218 1: variable.parameter.dfasm 219 2: keyword.operator.assignment.dfasm 220 3: constant.numeric.dfasm 221 222 - match: ',' 223 scope: punctuation.separator.dfasm 224 225 - match: '(?=;)' 226 pop: true 227 228 - match: '$' 229 pop: true 230 231 - match: '\s+' 232 233 # === String Contexts === 234 string: 235 - meta_scope: string.quoted.double.dfasm 236 237 - match: '"' 238 scope: string.quoted.double.dfasm 239 pop: true 240 241 - match: "\\\\[ntr0\\\\'\"]" 242 scope: constant.character.escape.dfasm 243 244 - match: '\\x[0-9a-fA-F]{2}' 245 scope: constant.character.escape.dfasm 246 247 - match: '\\' 248 scope: constant.character.escape.dfasm 249 250 raw_string: 251 - meta_scope: string.quoted.double.raw.dfasm 252 253 - match: '"' 254 scope: string.quoted.double.raw.dfasm 255 pop: true 256 257 byte_string: 258 - meta_scope: string.quoted.double.byte.dfasm 259 260 - match: '"' 261 scope: string.quoted.double.byte.dfasm 262 pop: true 263 264 - match: "\\\\[ntr0\\\\'\"]" 265 scope: constant.character.escape.dfasm 266 267 - match: '\\x[0-9a-fA-F]{2}' 268 scope: constant.character.escape.dfasm 269 270 - match: '\\' 271 scope: constant.character.escape.dfasm 272 273 char_literal: 274 - meta_scope: string.quoted.single.dfasm 275 276 - match: "'" 277 scope: string.quoted.single.dfasm 278 pop: true 279 280 - match: "\\\\[ntr0\\\\'\"]" 281 scope: constant.character.escape.dfasm 282 283 - match: '\\x[0-9a-fA-F]{2}' 284 scope: constant.character.escape.dfasm 285 286 - match: '\\' 287 scope: constant.character.escape.dfasm