{ "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", "name": "cell", "// Le fichier contient soit des fonctions, soit du code source.": "", "patterns": [ { "include": "#function" }, { "include": "#code" }, { "match": ".*", "name": "invalid.source.lang" } ], "// Dans le champ repository, on stocke et nomme toutes les regex.": "", "repository": { "// Regex caractérisant un float.": {}, "// Ici, l'ordre n'a pas d'important.": {}, "// Un type peut faire référence (include) à un autre type qui sera défini plus tard.": {}, "float": { "name": "constant.numeric.float.lang", "match": "\\b[0-9]+\\.[0-9]*(f|d)\\b" }, "hex": { "name": "constant.numeric.hex.lang", "match": "\\b0(x|X)[0-9a-fA-F]+\\b" }, "integer": { "name": "constant.numeric.integer.lang", "match": "\\b[0-9]+\\b" }, "number": { "// Regex caractérisant un int.": "", "// Il est important de mettre le cas le plus spécialisé en premier.": "", "// Si on avait mis integer en premier, on n'aurait jamais réussi à faire matcher float": "", "// car les parties entière et décimale seraient détectées comme int": "", "patterns": [ { "include": "#float" }, { "include": "#hex" }, { "include": "#integer" } ] }, "expression": { "// Pour faire simple, on dit qu'un expression, c'est soit :": "", "// - deux nombres avec un opérateur arithmétique au milieu,": "", "// - un nombre.": "", "patterns": [ { "match": "(.*)\\b\\s*(\\+|\\/|\\*|-)\\b\\s*(.*)\\b", "name": "string.regexp.expr.lang", "captures": { "1": { "patterns": [ { "include": "#number" } ] }, "2": { "name": "keyword.operator.expr.lang" }, "3": { "patterns": [ { "include": "#number" } ] } } }, { "include": "#number" } ] }, "primary_type": { "// On suppose que les types sont des nombres uniquement.": "", "// Si le type est inconnu, on le déclare invalide.": "", "// Attention à ne pas déclarer invalide comme fallthrough à chaque pattern.": "", "// Sinon, les patterns qui include le type s'arrêteront toujours au fallthrough": "", "// sans lire les étapes suivantes.": "", "patterns": [ { "match": "(int|short|char|double|float)", "name": "storage.type.lang" }, { "match": ".*", "name": "invalid.primary_type.lang" } ] }, "init_variable": { "// Une initialisation de variable se faire :": "", "// int variable = expression;": "", "patterns": [ { "name": "meta.expr.init_variable.lang", "match": "\\s*([^\\s]+)\\b\\s*(.+)\\b\\s*=\\s*(.+);", "captures": { "1": { "patterns": [ { "include": "#primary_type" } ] }, "2": { "name": "variable.name.lang" }, "3": { "patterns": [ { "include": "#expression" } ] } } } ] }, "if": { "// Un if a la syntaxe suivante :": "", "// if expression then": "", "// du code.": "", "// fi": "", "// La déclaration de la partie code est faite dans l'identifiant code ci-après": "", "begin": "^(\\s*)(if)(.*)(then)\\s*", "beginCaptures": { "2": { "name": "keyword.control.lang" }, "3": { "patterns": [ { "include": "#expression" } ] }, "4": { "name": "keyword.control.lang" } }, "// Ici, on utilise le groupe \\1 qui fait référence au groupe 1 de begin": "", "// Comme il n'est pas possible de détecter les fi correspondant aux if": "", "// dans le cas de if imbriqués, on utilise l'indentation pour la correspondance.": "", "end": "^(\\1)(fi)\\s*", "endCaptures": { "2": { "name": "keyword.control.lang" } }, "name": "meta.body.if.definition.lang", "patterns": [ { "include": "#code" } ] }, "code": { "// Le code représente des instructions entières.": "", "// Ici, on considère que des nombres et expression peuvent": "", "// être des instructions mais cela aurait pu être interdit.": "", "patterns": [ { "include": "#if" }, { "include": "#init_variable" }, { "include": "#expression" }, { "include": "#number" } ] }, "function": { "begin": "^\\s*(function)\\s+([^\\s]*)\\s*$", "beginCaptures": { "1": { "name": "storage.type.function.lang" }, "2": { "name": "entity.name.method.lang" } }, "end": "\\s*(end_function)\\s*", "endCaptures": { "1": { "name": "keyword.other.lang" } }, "name": "meta.body.function.definition.lang", "patterns": [ { "include": "#code" } ] } }, "scopeName": "source.lang" }