Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .tree-sitter-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"directories": [
"."
]
}
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "tree-sitter-inference"
description = "Inference grammar for tree-sitter"
version = "0.0.32"
version = "0.0.33"
authors = [
"Georgii Plotnikov <[email protected]>"
]
Expand Down
2 changes: 1 addition & 1 deletion Makefile

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 6 additions & 8 deletions debug.inf
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
fn foo() {
assume {
let x: u32 = @;
forall {
let y: u32 = @;
foobar(param1 : @, param2: 5);
///<do some checking for x and y>
}
fn type_check(exprs : [Expr]) -> () {
let env : Binding = Binding { a: "", b: 0, c: [] };
let mut i : i32 = 0;
loop exprs.len {
check_expr(exprs[i], env);
i = i + 1;
}
}
27 changes: 19 additions & 8 deletions grammar.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ module.exports = grammar({

extras: $ => [
/\s/,
$._comment,
$.comment,
],

rules: {
Expand Down Expand Up @@ -159,6 +159,7 @@ module.exports = grammar({
$._literal,
$.binary_expression,
$.function_call_expression,
$.struct_expression,
$.prefix_unary_expression,
$.parenthesized_expression,
$.uzumaki_keyword
Expand Down Expand Up @@ -189,10 +190,19 @@ module.exports = grammar({
field('function', $._lval_expression),
optional(field('type_parameters', alias($.type_argument_list, $.type_parameters))),
'(',
optional(sep1(seq(optional(seq(field('argument_name', $._name), ':')), field('argument', $._expression)), ',')),
optional(sep1(seq(optional(seq(field('argument_name', $._name), $._typedef_symbol)), field('argument', $._expression)), ',')),
')',
)),

struct_expression: $ => seq(
field('name', $._name),
$._lcb_symbol,
optional(sep1(
seq(field('field_name', $._name), $._typedef_symbol, field('field_value', $._expression)),
$._comma_symbol)),
$._rcb_symbol,
),

expression_statement: $ => seq(
$._expression,
$._terminal_symbol
Expand Down Expand Up @@ -299,11 +309,11 @@ module.exports = grammar({

struct_definition: $ => seq(
'struct',
field('struct_name', $.identifier),
field('name', $.identifier),
$._lcb_symbol,
repeat(choice(
seq(field('field', $.struct_field), ';'),
field('method', $.function_definition),
field('value', $.function_definition),
)),
$._rcb_symbol,
),
Expand Down Expand Up @@ -485,7 +495,7 @@ module.exports = grammar({

string_literal: $ => seq(
'"',
$._string_literal_content,
optional($._string_literal_content),
'"',
),

Expand All @@ -497,10 +507,10 @@ module.exports = grammar({

array_literal: $ => seq(
'[',
sep1(
optional(sep1(
$._expression,
',',
),
)),
']',
),

Expand Down Expand Up @@ -561,6 +571,7 @@ module.exports = grammar({
$._reserved_identifier,
),

_comment: _ => token(seq('///', /[^\n\r]*/)),
// Comments start with '///'
comment: _ => token(seq('///', /[^\n\r]*/)),
},
});
66 changes: 66 additions & 0 deletions highlight.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/usr/bin/env node

// Simple regex-based syntax highlighter for Inference language
const fs = require('fs');
const path = require('path');

const args = process.argv.slice(2);
if (args.length !== 1) {
console.error(`Usage: node ${path.basename(process.argv[1])} <file.inf>`);
process.exit(1);
}
const file = args[0];
let src;
try {
src = fs.readFileSync(file, 'utf8');
} catch (e) {
console.error(`Error reading file ${file}:`, e.message);
process.exit(1);
}

// Escape HTML
function escapeHtml(s) {
return s.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
}

// Define token patterns and classes
const patterns = [
{cls: 'comment', re: /^\/\/\/.*(?:\r?\n|$)/},
{cls: 'string', re: /^"(?:\\.|[^"\\])*"/},
{cls: 'type', re: /^(?:\b(?:i8|i16|i32|i64|u8|u16|u32|u64|bool)\b|\(\))/},
{cls: 'keyword', re: /^(?:\b(?:fn|forall|exists|assume|unique|loop|if|else|break|return|let|const|type|enum|struct|use|spec|external)\b)/},
{cls: 'boolean', re: /^(?:\b(?:true|false)\b)/},
{cls: 'number', re: /^-?\d+(?:\.\d+)?/},
{cls: 'operator', re: /^(?:->|::|\*\*|==|!=|<=|>=|&&|\|\||<<|>>|[=+\-*/%&|^<>])/},
{cls: 'punctuation', re: /^[{}\[\]();,]/},
{cls: 'identifier', re: /^\b[A-Za-z_]\w*\b/},
{cls: 'whitespace', re: /^\s+/},
{cls: 'text', re: /^./}
];

// Highlight
let out = '';
let pos = 0;
while (pos < src.length) {
let matched = false;
for (const {cls, re} of patterns) {
const m = re.exec(src.slice(pos));
if (!m) continue;
const tok = m[0];
const esc = escapeHtml(tok);
if (cls === 'whitespace' || cls === 'text') {
out += esc;
} else {
out += `<span class="${cls}">${esc}</span>`;
}
pos += tok.length;
matched = true;
break;
}
if (!matched) { out += escapeHtml(src[pos]); pos++; }
}

// Wrap in pre/code
process.stdout.write('<pre><code>' + out + '</code></pre>');
23 changes: 23 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const path = require('path');
const binding = require('./bindings/node');
// Load node type information (prefer the generated src/node-types.json)
let staticData;
try {
staticData = require(path.join(__dirname, 'src', 'node-types.json'));
} catch (e) {
try {
staticData = require(path.join(__dirname, 'node-types.json'));
} catch {
staticData = [];
}
}

// Attach the two properties that tree-sitter-highlight needs
// Expose node type names and types for tree-sitter-highlight (if used)
binding.nodeTypeNamesById = Array.isArray(staticData) ? staticData.map(e => e.type) : [];
binding.types = staticData;
// Prevent tree-sitter JS from re-initializing node subclasses (avoids version checks)
binding.nodeSubclasses = [];

// Export the binding object (with .language) so tree-sitter JS can unwrap it properly
module.exports = binding;
Loading